Skip to content

Commit b40a8ce

Browse files
committed
Fix: Added filters.
1 parent 45eb074 commit b40a8ce

File tree

9 files changed

+14263
-121
lines changed

9 files changed

+14263
-121
lines changed

.env

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
NODE_ENV=test
2+
REST_API_URL=http://localhost:8080/api
3+
GRAPHQL_API_URL=http://localhost:8080/graphql
4+
GATSBY_UPDOWN_ID=1
5+
GATSBY_UPDOWN_API=1

config/siteConfig.js

+3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ module.exports = {
1818
status: {
1919
site: 'https://status.rickandmortyapi.com',
2020
},
21+
gender: {
22+
site: 'https://status.rickandmortyapi.com',
23+
},
2124
support: {
2225
kofi: 'https://ko-fi.com/axelfuh',
2326
buyMeACoffee: 'https://buymeacoffee.com/axelfuh',

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
},
4141
"devDependencies": {
4242
"@testing-library/cypress": "^7.0.2",
43+
"babel-eslint": "^10.1.0",
4344
"cypress": "^4.12.1",
4445
"eslint": "^7.15.0",
4546
"eslint-config-afuh": "^0.2.0",

src/components/home/characterCard.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ const ContentWrapper = styled.div`
129129
}}
130130
`
131131

132-
const Card = ({ image, name, url, status, species, location, episode }) => {
132+
const Card = ({ image, name, url, status, species, location, episode, gender }) => {
133133
const [loading, setLoading] = useState(true)
134134
const headingMaxLength = 23
135135

@@ -144,7 +144,7 @@ const Card = ({ image, name, url, status, species, location, episode }) => {
144144
<h2>{name}</h2>
145145
</ExternalLink>
146146
<span className="status">
147-
<span className="status__icon" /> {status} - {species}
147+
<span className="status__icon" /> {status} - {species} - {gender}
148148
</span>
149149
</div>
150150

@@ -176,6 +176,7 @@ Card.propTypes = {
176176
name: PropTypes.string,
177177
url: PropTypes.string,
178178
}).isRequired,
179+
gender: PropTypes.string.isRequired,
179180
}
180181

181182
export default Card

src/components/home/showcase.js

+158-9
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
1-
import React from 'react'
1+
import React, { useState , useEffect } from 'react'
22
import styled, { css } from 'styled-components'
3-
4-
import { useRandomCharacters } from '../../utils/hooks'
53
import { Spinner } from '../shared'
64
import Card from './characterCard'
5+
import { useSiteMeta } from '../../utils/hooks'
6+
import { useRickAndMortyStats } from '../../utils/hooks'
77

88
const Wrapper = styled.section(
99
({ theme }) => css`
10-
${theme.mixins.flex}
11-
padding: ${theme.spacing.rem(72)} 0;
10+
// ${theme.mixins.flex}
11+
padding: ${theme.spacing.rem(40)} 0;
1212
background: #272b33;
1313
min-height: calc(50vh - ${theme.navHeight}px);
14-
1514
${theme.media.phone(css`
1615
padding: ${theme.spacing._24};
1716
`)}
@@ -20,18 +19,168 @@ const Wrapper = styled.section(
2019

2120
const Inner = styled.div(
2221
({ theme }) => css`
23-
${theme.mixins.flex};
22+
${theme.mixins.flex}
2423
flex-wrap: wrap;
2524
max-width: 1920px;
2625
`,
2726
)
2827

28+
const Flex = styled.h1(
29+
({ theme }) => css`
30+
z-index: 1;
31+
display: flex;
32+
justify-content: center;
33+
margin: 0 0.75rem;
34+
max-width: 1920px;
35+
${theme.media.phone(css`
36+
justify-content: space-between;
37+
margin: 0rem;
38+
`)}
39+
`,
40+
)
41+
42+
const Select = styled.select(
43+
({ theme }) => css`
44+
border: 1px solid rgb(255, 152, 0);
45+
border-radius: 8px;
46+
padding: 6px;
47+
width: 230px;
48+
margin: 0.75rem;
49+
color: #f5f5f5;
50+
background: rgb(60, 62, 68);
51+
font-size: ${theme.spacing.rem(16)};
52+
${theme.media.phone(css`
53+
font-size: ${theme.spacing.rem(14)};
54+
width: 100%;
55+
`)}
56+
`,
57+
)
58+
59+
60+
2961
const Showcase = () => {
30-
const { loading, data } = useRandomCharacters({ total: 6 })
62+
const [state, setState] = useState({
63+
status: 'all',
64+
gender: 'all',
65+
data:[],
66+
loading:false,
67+
filteredData:[]
68+
})
69+
const getRandomNums = ({ max, total }) => {
70+
const arr = []
71+
const randomNum = () => Math.floor(Math.random() * max + 1)
72+
73+
if (total === 1) {
74+
return randomNum()
75+
}
76+
77+
while (arr.length < total) {
78+
const num = randomNum()
79+
if (arr.indexOf(num) > -1) {
80+
continue
81+
}
82+
arr[arr.length] = num
83+
}
84+
return arr
85+
}
86+
87+
const graphqlQuery = () => ({
88+
query: `
89+
query {
90+
characters(page: 1) { # Start with page 1
91+
info {
92+
next
93+
}
94+
results {
95+
id
96+
name
97+
status
98+
gender
99+
species
100+
image
101+
episode {
102+
name
103+
id
104+
}
105+
location {
106+
name
107+
id
108+
}
109+
}
110+
}
111+
}
112+
`,
113+
variables: { },
114+
})
115+
116+
const { siteUrl } = useSiteMeta()
117+
const {
118+
characters: { info },
119+
} = useRickAndMortyStats()
120+
121+
const fetchFromAPI = async ({status=state.status , gender=state.gender}) => {
122+
const res = await fetch(`${siteUrl}/graphql`, {
123+
method: 'POST',
124+
body: JSON.stringify(graphqlQuery(getRandomNums({ max: info.count, total:20 }))),
125+
headers: {
126+
'content-type': 'application/json',
127+
},
128+
}).catch(() => {
129+
setLoading(false)
130+
})
131+
if (res && res.ok) {
132+
const { data } = await res.json()
133+
let filteredCharacters = JSON.parse(JSON.stringify(data.characters.results))
134+
if(status!=="all"){
135+
filteredCharacters= filteredCharacters.filter((char) =>char.status===status)
136+
}
137+
if(gender!=="all"){
138+
filteredCharacters= filteredCharacters.filter((char) =>char.gender===gender)
139+
}
140+
const characters = filteredCharacters.map((item) => ({
141+
...item,
142+
url: `${siteUrl}/api/character/${item.id}`,
143+
episode: {
144+
name: item.episode[0].name,
145+
url: `${siteUrl}/api/episode/${item.episode[0].id}`,
146+
},
147+
location: {
148+
name: item.location.name,
149+
url: `${siteUrl}/api/location/${item.location.id}`,
150+
},
151+
}))
152+
//sessionStorage.setItem(CACHE_KEY, JSON.stringify(characters))
153+
setState((prev)=>({...prev, data:data.characters.results, filteredData:characters, status, gender}))
154+
}
155+
}
156+
157+
158+
159+
useEffect(()=>{
160+
fetchFromAPI({})
161+
return()=>{
162+
console.log("showcase unmounted")
163+
}
164+
} ,[])
31165

32166
return (
33167
<Wrapper>
34-
<Inner>{loading ? <Spinner /> : data.map((char) => <Card key={char.id} {...char} />)}</Inner>
168+
<Flex>
169+
<Select name="status" id="status" onChange={() => fetchFromAPI({status:document.getElementById('status').value})}>
170+
<option value="all">All</option>
171+
<option value="Alive">Alive</option>
172+
<option value="Unknown">Unknown</option>
173+
<option value="Dead">Dead</option>
174+
</Select>
175+
<Select name="gender" id="gender" onChange={() => fetchFromAPI({gender:document.getElementById('gender').value})}>
176+
<option value="all">All</option>
177+
<option value="Female">Female</option>
178+
<option value="Male">Male</option>
179+
<option value="Genderless">Genderless</option>
180+
<option value="Unknown">Unknown</option>
181+
</Select>
182+
</Flex>
183+
<Inner>{state.loading ? <Spinner /> : state.filteredData.map((char) => <Card key={char.id} {...char} />)}</Inner>
35184
</Wrapper>
36185
)
37186
}

src/components/layout/footer.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react'
22
import styled, { css } from 'styled-components'
3-
import { GoMarkGithub, GoHeart } from 'react-icons/go'
4-
import { FaTwitter } from 'react-icons/fa'
3+
import { GoHeart } from 'react-icons/go'
4+
import { FaTwitter ,FaGithub} from 'react-icons/fa'
55
import { Link } from 'gatsby'
66

77
import { useRickAndMortyStats, useSiteMeta, useServerStatus } from '../../utils/hooks'
@@ -146,7 +146,7 @@ const Icons = () => {
146146
const { github, userTwitter } = useSiteMeta()
147147

148148
const footerLinks = [
149-
{ to: github.api, Icon: GoMarkGithub, title: 'GitHub' },
149+
{ to: github.api, Icon: FaGithub, title: 'GitHub' },
150150
{ to: `https://twitter.com/${userTwitter}`, Icon: FaTwitter, title: 'Twitter' },
151151
{ to: '/support-us', Icon: GoHeart, title: 'Support Us' },
152152
]

src/utils/hooks/index.js

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
export { useSiteMeta } from './useSiteMeta'
22
export { useRickAndMortyStats } from './useRickAndMortyStats'
3-
export { useRandomCharacters } from './useRandomChars'
43
export { useMobileSidebar } from './useMobileSidebar'
54
export { useServerStatus } from './useServerStatus'

src/utils/hooks/useRandomChars.js

-106
This file was deleted.

0 commit comments

Comments
 (0)