Skip to content

Commit

Permalink
Initiated project
Browse files Browse the repository at this point in the history
  • Loading branch information
premell committed Aug 23, 2021
1 parent 8f3d9b2 commit d2180ba
Show file tree
Hide file tree
Showing 64 changed files with 6,461 additions and 332 deletions.
4 changes: 4 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"presets": ["next/babel"],
"plugins": [["styled-components", { "ssr": true }]]
}
225 changes: 225 additions & 0 deletions atoms.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
import { atom, selector } from "recoil";
import { recoilPersist } from "recoil-persist";

import { SORTING_METHODS, STATS } from "@/shared/constants"

const { persistAtom } = recoilPersist();

// export const popupMessage = atom({
// key: "popupMessage",
// default: {
// show: false,
// message: "hello",
// type: "positive",
// },
// });


// export const numberOfMatchedPokemon = atom({
// key: "numberOfMatchedPokemon",
// default: 0
// });

export const pokemonPerPage = atom({
key: "pokemonPerPage",
default: 20
});

export const currentPage = atom({
key: "currentPage",
default: 1
});

export const priceFilter = atom({
key: "priceFilter",
default: {
currentRange: {
min: 0,
max: 2500,
},
range: {
min: 0,
max: 2500,
},
isFiltering: false,
},
});

export const statsFilter = atom({
key: "statsFilter",
default: {
ATTACK: {
name: STATS.ATTACK,
currentRange: {
min: 0,
max: 200,
},
range: {
min: 0,
max: 200,
},
isFiltering: false,
},
DEFENSE: {
name: STATS.DEFENSE,
currentRange: {
min: 0,
max: 250,
},
range: {
min: 0,
max: 250,
},
isFiltering: false,
},
HP: {
name: STATS.HP,
currentRange: {
min: 0,
max: 300,
},
range: {
min: 0,
max: 300,
},
isFiltering: false,
},
SPECIAL_ATTACK: {
name: STATS.SPECIAL_ATTACK,
currentRange: {
min: 0,
max: 200,
},
range: {
min: 0,
max: 200,
},
isFiltering: false,
},
SPECIAL_DEFENSE: {
name: STATS.SPECIAL_DEFENSE,
currentRange: {
min: 0,
max: 300,
},
range: {
min: 0,
max: 300,
},
isFiltering: false,
},
SPEED: {
name: STATS.SPEED,
currentRange: {
min: 0,
max: 200,
},
range: {
min: 0,
max: 200,
},
isFiltering: false,
}
},
});

export const typeFilter = atom({
key: "typeFilter",
default: {
types: [
],
isFiltering: false,
},
});

export const abilityFilter = atom({
key: "abilityFilter",
default: {
abilities: [
],
isFiltering: false,
},
});

export const anyFilterActive = selector({
key: 'anyFilterActive',
get: ({ get }) => {
let isFiltering = false
if (get(abilityFilter).isFiltering) isFiltering = true
else if (get(typeFilter).isFiltering) isFiltering = true
else if (get(priceFilter).isFiltering) isFiltering = true
const localStatsFilter = get(statsFilter)
Object.keys(localStatsFilter).forEach((key) => {
if (localStatsFilter[key].isFiltering) isFiltering = true
})
return isFiltering
}
});

export const searchQuery = atom({
key: "searchQuery",
default: ""
});

export const sortingMethod = atom({
key: "sortingMethod",
default: SORTING_METHODS.RELEASE_OLDEST_FIRST

})

// export const sortedPokemon = atom({
// key: "sortedPokemon ",
// default: []
// })


export const favorites = atom({
key: "favorites",
default: {
pokemon: {
},
}
});

export const cart = atom({
key: "cart",
default: {
pokemon: [],
total: 0,
}
});


// export const generalModalMessage = atom({
// key: "generalModalMessage ",
// default: {
// message: "",
// show: false,
// type: "positive",
// }
// })

export const numberOfMatchedPokemon = atom({
key: "numberOfMatchedPokemon",
default: 1000,
})

export const showModalTemporarily = atom({
key: "showModalTemporarily",
default: false
})

export const showModalWithTimer = atom({
key: "showModalWithTimer",
default: false
})

export const showCartModal = atom({
key: "showCartModal",
default: false
})

export const showCartModalInstantly = atom({
key: "showCartModalInstantly",
default: true
})
23 changes: 23 additions & 0 deletions components/Footer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Links, BoldRegularText } from "shared/components";

import styled from "styled-components";

const StyledFooter = styled.div`
color: white;
background-color: ${(p) => p.theme.colors.gray_100};
height: 300px;
width: 100%;
`;

const Footer = () => {
return (
<StyledFooter>
<p>This is a pokemon website</p>
<BoldRegularText>Contact me</BoldRegularText>
<p>Email: [email protected]</p>
<Links />
</StyledFooter>
);
};

export default Footer;
43 changes: 43 additions & 0 deletions components/Layout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import styled from "styled-components";
import { useRouter } from "next/router";

import { useEffect } from "react";
import Navbar from "./Navbar";
import Footer from "./Footer";

import { useCartModal } from "shared/hooks";

const MainContainer = styled.div`
width: 100vw;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: ${(p) => p.theme.colors.gray_10};
`;

const MainContent = styled.div`
width: 100%;
max-width: 1900px;
margin-top: 76px;
`;
const Layout = ({ children }) => {
const router = useRouter();

const { hideWithTimer, hideTemporarly, hideInstantly } = useCartModal();

useEffect(() => {
hideWithTimer();
hideTemporarly();
hideInstantly();
}, [router.asPath]);

return (
<MainContainer>
<Navbar />
<MainContent>{children}</MainContent>
<Footer />
</MainContainer>
);
};
export default Layout;
92 changes: 92 additions & 0 deletions components/MainPokemonContainer/FilterPanel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { useRecoilState, useResetRecoilState } from "recoil";
import { priceFilter as priceFilterAtoms } from "atoms.js";
import { statsFilter as statsFilterAtoms } from "atoms.js";
import { typeFilter as typeFilterAtoms } from "atoms.js";
import { abilityFilter as abilityFilterAtoms } from "atoms.js";

import { PriceFilterFlair, NumberFilterFlair, FilterBox, Cross, AbilityFilterFlair, StyledFilterContainer, RemoveAllFilters } from "./Styles"
import TypeFlair from "@/shared/TypeFlair"
import { useEffect } from "react";

import { formatAsUSDWithoutTrailingZeros } from "shared/javascript"


const FilterPanel = () => {

const [priceFilter, setPriceFilter] = useRecoilState(priceFilterAtoms);
const [statsFilter, setStatsFilter] = useRecoilState(statsFilterAtoms);
const [typeFilter, setTypeFilter] = useRecoilState(typeFilterAtoms);
const [abilityFilter, setAbilityFilter] = useRecoilState(abilityFilterAtoms);

const defaultPriceFilter = useResetRecoilState(priceFilterAtoms)
const defaultStatsFilter = useResetRecoilState(statsFilterAtoms)
const defaultTypeFilter = useResetRecoilState(typeFilterAtoms)
const defaultAbilityFilter = useResetRecoilState(abilityFilterAtoms)
const removeAllFilters = () => {
defaultPriceFilter()
defaultStatsFilter()
defaultTypeFilter()
defaultAbilityFilter()
}

const removePrice = () => {
//setPriceFilter({ ...priceFilter, currentRange: { min: 0, max: 2500 }, isFiltering: false })
defaultPriceFilter()
}

const removeStat = (stat) => {
setStatsFilter(statsFilter => ({ ...statsFilter, [stat]: { ...statsFilter.[stat], currentRange: statsFilter.[stat].range, isFiltering: false } }))
}

const removeType = (type) => {
const updatedTypes = typeFilter.types.filter((arrayType) => arrayType !== type)
let isFiltering = true
if (updatedTypes.length === 0) isFiltering = false
setTypeFilter({ types: updatedTypes, isFiltering: isFiltering })
}

const removeAbility = (ability) => {
const updatedAbilities = abilityFilter.abilities.filter((arrayAbility) => arrayAbility !== ability)
let isFiltering = true
if (updatedAbilities.length === 0) isFiltering = false
setAbilityFilter({ abilities: updatedAbilities, isFiltering: isFiltering })
}

const getIsAnyFilterActive = () => {
let isActive = false
if (abilityFilter.isFiltering) isActive = true
else if (typeFilter.isFiltering) isActive = true
else if (priceFilter.isFiltering) isActive = true

Object.keys(statsFilter).forEach((key) => {
if (statsFilter[key].isFiltering) isActive = true
})
return isActive
}

const isAnyFilterActive = getIsAnyFilterActive()



//return <RegularText style={{ margin: 0 }}>{`Price: ${formatAsUSDWithoutTrailingZeros(min)} - ${formatAsUSDWithoutTrailingZeros(max)}`}</RegularText>
//<Cross handleClick={removePrice} />
return (
<StyledFilterContainer>
{priceFilter.isFiltering && <FilterBox handleClick={removePrice} text={`Price: ${formatAsUSDWithoutTrailingZeros(priceFilter.currentRange.min)} - ${formatAsUSDWithoutTrailingZeros(priceFilter.currentRange.max)}`} />}
{typeFilter.isFiltering && typeFilter.types.map((type) => <FilterBox handleClick={() => removeType(type)} text={type} />)}
{abilityFilter.isFiltering && abilityFilter.abilities.map((ability) => <FilterBox handleClick={() => removeAbility(ability)} text={ability} />)}
{Object.keys(statsFilter).map((key) => {
if (statsFilter[key].isFiltering) return (
<FilterBox handleClick={() => removeStat(key)} text={`${statsFilter[key].name}: ${statsFilter[key].currentRange.min} - ${statsFilter[key].currentRange.max}`} />
)
}
)}
{isAnyFilterActive ? <RemoveAllFilters handleClick={removeAllFilters} /> : null}
</StyledFilterContainer>
)
}
// <FilterBox key={key}><NumberFilterFlair min={statsFilter[key].currentRange.min}
// max={statsFilter[key].currentRange.max} name={statsFilter[key].name} /> <Cross handleClick={() => removeStat(key)} /></FilterBox>
// )

export default FilterPanel
Loading

0 comments on commit d2180ba

Please sign in to comment.