Merge pull request #138 from byurhanbeyzat/issue-120-add-filter-buttons

Issue 120: Added filter buttons for computers and phones
This commit is contained in:
Wes Bos 2020-01-08 10:25:37 -05:00 committed by GitHub
commit 994d85e720
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 158 additions and 23 deletions

View file

@ -1,5 +1,5 @@
import people from './src/data'; import people from './src/data.js';
import { tags, countries } from './src/util/stats'; import { tags, countries, computers, phones } from './src/util/stats';
function sourceNodes({ actions, createNodeId, createContentDigest }) { function sourceNodes({ actions, createNodeId, createContentDigest }) {
// Add People to the GraphQL API, we randomize the data on each build so no one gets their feelings hurt // Add People to the GraphQL API, we randomize the data on each build so no one gets their feelings hurt
@ -38,7 +38,6 @@ function sourceNodes({ actions, createNodeId, createContentDigest }) {
actions.createNode({ ...tag, ...nodeMeta }); actions.createNode({ ...tag, ...nodeMeta });
}); });
console.log(countries());
// Add Countries to GraphQL API // Add Countries to GraphQL API
countries().forEach(country => { countries().forEach(country => {
const nodeMeta = { const nodeMeta = {
@ -55,6 +54,38 @@ function sourceNodes({ actions, createNodeId, createContentDigest }) {
actions.createNode({ ...country, ...nodeMeta }); actions.createNode({ ...country, ...nodeMeta });
}); });
// Add Computers to GraphQL API
computers().forEach(computer => {
const nodeMeta = {
id: createNodeId(`computer-${computer.name}`),
parent: null,
children: [],
internal: {
type: `Computer`,
mediaType: `text/html`,
content: JSON.stringify(computer),
contentDigest: createContentDigest(computer),
},
};
actions.createNode({ ...computer, ...nodeMeta });
});
// Add Phones to GraphQL API
phones().forEach(phone => {
const nodeMeta = {
id: createNodeId(`phone-${phone.name}`),
parent: null,
children: [],
internal: {
type: `Phone`,
mediaType: `text/html`,
content: JSON.stringify(phone),
contentDigest: createContentDigest(phone),
},
};
actions.createNode({ ...phone, ...nodeMeta });
});
} }
export { sourceNodes }; export { sourceNodes };

View file

@ -3,10 +3,15 @@ import styled from 'styled-components';
import FilterContext from '../context/FilterContext'; import FilterContext from '../context/FilterContext';
export default function Topics() { export default function Topics() {
const { countries, tags, currentTag, setCurrentTag } = useContext( const {
FilterContext countries,
); tags,
console.log(countries); phones,
computers,
currentTag,
setCurrentTag,
} = useContext(FilterContext);
return ( return (
<Tags> <Tags>
{tags.map(tag => ( {tags.map(tag => (
@ -47,6 +52,45 @@ export default function Topics() {
<TagCount>{tag.count}</TagCount> <TagCount>{tag.count}</TagCount>
</Tag> </Tag>
))} ))}
{computers.map(tag => (
<label
className={`tag ${tag.name === currentTag ? 'currentTag' : ''}`}
htmlFor={`filter-${tag.name}`}
key={`filter-${tag.name}`}
title={tag.name}
>
<input
type="radio"
name="computer"
id={`filter-${tag.name}`}
value={tag.name}
checked={tag.name === currentTag}
onChange={e => setCurrentTag(e.currentTarget.value)}
/>
{tag.name}
<span className="count">{tag.count}</span>
</label>
))}
{phones.map(tag => (
<label
className={`tag ${tag.name === currentTag ? 'currentTag' : ''}`}
htmlFor={`filter-${tag.name}`}
key={`filter-${tag.name}`}
title={tag.name}
>
<input
type="radio"
name="tag"
id={`filter-${tag.name}`}
value={tag.name}
checked={tag.name === currentTag}
onChange={e => setCurrentTag(e.currentTarget.value)}
/>
{tag.name}
<span className="count">{tag.count}</span>
</label>
))}
</Tags> </Tags>
); );
} }

View file

@ -6,7 +6,7 @@ const FilterContext = createContext();
const FilterProvider = function({ children }) { const FilterProvider = function({ children }) {
const [currentTag, setCurrentTag] = useState('all'); const [currentTag, setCurrentTag] = useState('all');
const { allTag, allCountry } = useStaticQuery(graphql` const { allTag, allCountry, allComputer, allPhone } = useStaticQuery(graphql`
query FilterQuery { query FilterQuery {
allTag { allTag {
nodes { nodes {
@ -21,6 +21,18 @@ const FilterProvider = function({ children }) {
name name
} }
} }
allComputer {
nodes {
count
name
}
}
allPhone {
nodes {
count
name
}
}
} }
`); `);
return ( return (
@ -28,6 +40,8 @@ const FilterProvider = function({ children }) {
value={{ value={{
tags: allTag.nodes, tags: allTag.nodes,
countries: allCountry.nodes, countries: allCountry.nodes,
computers: allComputer.nodes,
phones: allPhone.nodes,
currentTag, currentTag,
setCurrentTag, setCurrentTag,
}} }}

View file

@ -188,7 +188,7 @@ const pages = [
emoji: '😄', emoji: '😄',
country: '🇺🇸', country: '🇺🇸',
computer: 'apple', computer: 'apple',
phone: 'apple', phone: 'iphone',
tags: [ tags: [
'JavaScript', 'JavaScript',
'React', 'React',
@ -388,7 +388,7 @@ const pages = [
tags: ['JavaScript', 'Developer', 'Event Organizer', 'Teacher', 'Vue'], tags: ['JavaScript', 'Developer', 'Event Organizer', 'Teacher', 'Vue'],
}, },
{ {
name: 'David O\'Trakoun', name: "David O'Trakoun",
description: 'Software Engineer', description: 'Software Engineer',
url: 'https://www.davidosomething.com/uses/', url: 'https://www.davidosomething.com/uses/',
twitter: '@davidosomething', twitter: '@davidosomething',
@ -396,25 +396,19 @@ const pages = [
country: '🇺🇸', country: '🇺🇸',
computer: 'linux', computer: 'linux',
phone: 'android', phone: 'android',
tags: [ 'Developer' ], tags: ['Developer'],
}, },
{ {
name: 'Dean Harris', name: 'Dean Harris',
description: 'Front End Developer. Husband. Skateboarder. Occasional blogger', description:
'Front End Developer. Husband. Skateboarder. Occasional blogger',
url: 'https://deanacus.com/uses/', url: 'https://deanacus.com/uses/',
twitter: '@deanacus', twitter: '@deanacus',
emoji: '🛹', emoji: '🛹',
country: '🇦🇺', country: '🇦🇺',
computer: 'apple', computer: 'apple',
phone: 'iphone', phone: 'iphone',
tags: [ tags: ['Developer', 'Font End', 'JavaScript', 'React', 'Node', 'PHP'],
'Developer',
'Font End',
'JavaScript',
'React',
'Node',
'PHP',
],
}, },
{ {
name: 'Michael Hoffmann', name: 'Michael Hoffmann',
@ -425,7 +419,7 @@ const pages = [
country: '🇩🇪', country: '🇩🇪',
computer: 'apple', computer: 'apple',
phone: 'iphone', phone: 'iphone',
tags: [ 'Developer', 'Blogger', 'Angular' ], tags: ['Developer', 'Blogger', 'Angular'],
}, },
{ {
name: 'Michael Le', name: 'Michael Le',
@ -445,7 +439,7 @@ const pages = [
'JavaScript', 'JavaScript',
'React', 'React',
'Node', 'Node',
'Vue' 'Vue',
], ],
}, },
{ {

View file

@ -31,7 +31,9 @@ function IndexPage() {
person => person =>
currentTag === 'all' || currentTag === 'all' ||
person.tags.includes(currentTag) || person.tags.includes(currentTag) ||
currentTag === person.country currentTag === person.country ||
currentTag === person.computer ||
currentTag === person.phone
); );
return ( return (
<Layout> <Layout>

View file

@ -49,3 +49,53 @@ export function tags() {
return [{ name: 'all', count: people.length }, ...tags]; return [{ name: 'all', count: people.length }, ...tags];
} }
export function computers() {
const data = people
.map(person => ({
name: person.computer,
}))
.reduce((acc, computer) => {
if (acc[computer.name]) {
// exists, update
acc[computer.name].count += 1;
} else {
acc[computer.name] = {
...computer,
count: 1,
};
}
return acc;
}, {});
const sorted = Object.entries(data)
.map(([, computer]) => computer)
.sort((a, b) => b.count - a.count);
return sorted;
}
export function phones() {
const data = people
.map(person => ({
name: person.phone,
}))
.reduce((acc, phone) => {
if (acc[phone.name]) {
// exists, update
acc[phone.name].count = acc[phone.name].count + 1;
} else {
acc[phone.name] = {
...phone,
count: 1,
};
}
return acc;
}, {});
const sorted = Object.entries(data)
.map(([, phone]) => phone)
.sort((a, b) => b.count - a.count);
return sorted;
}