Skip to content

Commit

Permalink
Able to filter by tag
Browse files Browse the repository at this point in the history
  • Loading branch information
niksudan committed Jun 18, 2017
1 parent 7e96d42 commit d6cc55a
Show file tree
Hide file tree
Showing 13 changed files with 149 additions and 59 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
},
"dependencies": {
"isomorphic-fetch": "^2.2.1",
"lodash": "^4.17.4",
"react": "^15.4.2",
"react-dom": "^15.4.2",
"react-fontawesome": "^1.6.1",
Expand Down
9 changes: 9 additions & 0 deletions src/actions/projects.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,12 @@ export const unselectProject = () => {
export const loadProjects = () => ({
type: actions.LOAD_PROJECTS,
});

export const setFilter = (filter) => ({
type: actions.SET_FILTER,
filter,
});

export const clearFilter = () => ({
type: actions.CLEAR_FILTER,
});
2 changes: 1 addition & 1 deletion src/components/Infobox.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const Infobox = ({ dispatch, infobox }) => (
dispatch(closeInfobox());
browserHistory.push('/');
}}
origin="top right"
origin="bottom right"
>
<InfoboxLarge />
</Modal>
Expand Down
40 changes: 40 additions & 0 deletions src/components/Tag.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React from 'react';
import FontAwesome from 'react-fontawesome';

const Tag = ({ tag, children }) => (
<h6 key={tag} className={`tag tag--${tag}`}>
{tag === 'game' &&
<FontAwesome name="gamepad" />
}
{tag === 'cancelled' &&
<FontAwesome name="ban" />
}
{tag === 'article' &&
<FontAwesome name="book" />
}
{tag === 'open-source' &&
<FontAwesome name="code-fork" />
}
{tag === 'music' &&
<FontAwesome name="music" />
}
{tag === 'podcast' &&
<FontAwesome name="podcast" />
}
{tag === 'video' &&
<FontAwesome name="youtube-play" />
}
{tag === 'collaboration' &&
<FontAwesome name="users" />
}
{tag === 'in-development' &&
<FontAwesome name="edit" />
}
{tag === 'clear' &&
<FontAwesome name="times-circle" />
}
{children}
</h6>
);

export default Tag;
41 changes: 41 additions & 0 deletions src/components/TagFilter.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from 'react';
import { findIndex, orderBy } from 'lodash';
import { connect } from 'react-redux';
import Tag from './Tag';
import projects from '../data/projects.json';
import { setFilter, clearFilter } from '../actions/projects';
import './styles/TagFilter.css';

const TagFilter = ({ dispatch }) => {
let tags = [];
projects.forEach((project) => {
project.tags.forEach((tag) => {
const tagIndex = findIndex(tags, { name: tag });
if (tagIndex === -1) {
tags.push({ name: tag, count: 1 });
} else {
const currentTag = tags[tagIndex];
tags[tagIndex] = { name: tag, count: currentTag.count + 1 };
}
});
});
tags = orderBy(tags, ['count', 'name'], ['desc', 'asc']);
return (
<div className="tagfilter">
{tags.map((tag) => (
<a key={tag.name} onClick={() => { dispatch(setFilter(tag.name)) }}>
<Tag tag={tag.name}>
{tag.name} ({tag.count})
</Tag>
</a>
))}
<a onClick={() => { dispatch(clearFilter()) }}>
<Tag tag="clear">
clear
</Tag>
</a>
</div>
);
};

export default connect()(TagFilter);
33 changes: 3 additions & 30 deletions src/components/TagList.jsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,13 @@
import React from 'react';
import FontAwesome from 'react-fontawesome';
import Tag from './Tag';
import './styles/TagList.css';

const TagList = ({ tags }) => (
<div className="taglist">
{tags.map((tag) => (
<h6 key={tag} className={`tag tag--${tag}`}>
{tag === 'game' &&
<FontAwesome name="gamepad" />
}
{tag === 'cancelled' &&
<FontAwesome name="ban" />
}
{tag === 'article' &&
<FontAwesome name="book" />
}
{tag === 'open-source' &&
<FontAwesome name="code-fork" />
}
{tag === 'music' &&
<FontAwesome name="music" />
}
{tag === 'podcast' &&
<FontAwesome name="podcast" />
}
{tag === 'video' &&
<FontAwesome name="youtube-play" />
}
{tag === 'collaboration' &&
<FontAwesome name="users" />
}
{tag === 'in-development' &&
<FontAwesome name="edit" />
}
<Tag key={tag} tag={tag}>
{tag}
</h6>
</Tag>
))}
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion src/components/styles/Infobox.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.infobox-small {
position: fixed;
top: 0;
bottom: 0;
right: 0;
display: flex;
align-items: center;
Expand Down
12 changes: 12 additions & 0 deletions src/components/styles/TagFilter.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.tagfilter {
margin: 1rem 0;
}

.tagfilter .tag {
margin: 2px;
}

.tagfilter .tag.tag--clear {
border-color: #ff6666;
color: #ff6666;
}
4 changes: 2 additions & 2 deletions src/components/styles/TagList.css
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
margin-left: 5px;
}

.tag.tag--cancelled {
.taglist .tag.tag--cancelled {
border-color: #ff6666;
color: #ff6666;
}

.tag.tag--in-development {
.taglist .tag.tag--in-development {
border-color: #6fffe9;
color: #6fffe9;
}
2 changes: 2 additions & 0 deletions src/constants/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ export const CLOSE_INFOBOX = 'CLOSE_INFOBOX';
export const SELECT_PROJECT = 'SELECT_PROJECT';
export const UNSELECT_PROJECT = 'UNSELECT_PROJECT';
export const LOAD_PROJECTS = 'LOAD_PROJECTS';
export const SET_FILTER = 'SET_FILTER';
export const CLEAR_FILTER = 'CLEAR_FILTER';
36 changes: 20 additions & 16 deletions src/reducers/projects.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { assign } from 'lodash';
import * as actions from '../constants/actions';
import projects from '../data/projects';

Expand All @@ -7,37 +8,40 @@ const initialState = {
page: 0,
current: null,
isOpen: false,
filter: false,
};

export default (state = initialState, action) => {
switch (action.type) {
case actions.SELECT_PROJECT:
if (state.items.length >= action.index) {
return {
items: state.items,
activeItems: state.activeItems,
return assign({}, state, {
current: state.items[action.index],
isOpen: true,
page: state.page,
};
});
}
return state;
case actions.UNSELECT_PROJECT:
return {
items: state.items,
activeItems: state.activeItems,
current: state.current,
return assign({}, state, {
isOpen: false,
page: state.page,
};
});
case actions.LOAD_PROJECTS:
return {
items: state.items,
return assign({}, state, {
activeItems: state.items.slice(0, 12 * (state.page + 2)),
current: state.current,
isOpen: state.isOpen,
page: state.page + 1,
}
});
case actions.SET_FILTER:
return assign({}, state, {
filter: action.filter,
activeItems: state.items,
page: 0,
});
case actions.CLEAR_FILTER:
return assign({}, state, {
filter: false,
activeItems: projects.slice(0, 12),
page: 0,
});
default:
return state;
}
Expand Down
24 changes: 16 additions & 8 deletions src/views/Index.js → src/views/Index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import InfiniteScroll from 'react-infinite-scroller';
import Panel from '../components/Panel';
import Project from '../components/Project';
import Modal from '../components/Modal';
import TagFilter from '../components/TagFilter';
import { MOTION_MODAL } from '../constants/motion';
import { unselectProject, loadProjects } from '../actions/projects';

const Index = ({ dispatch, projects }) => (
const Index = ({ dispatch, projects, filter }) => (
<div className="app__view">
<TagFilter />
<InfiniteScroll
pageStart={projects.page}
loadMore={() => {
Expand All @@ -19,13 +21,18 @@ const Index = ({ dispatch, projects }) => (
hasMore={projects.items.length > projects.activeItems.length}
loader={<div />}
>
{projects.activeItems.map((project, index) => (
<Panel
key={index}
index={index}
data={project}
/>
))}
{projects.activeItems.map((project, index) => {
if (filter === false || project.tags.indexOf(filter) !== -1) {
return (
<Panel
key={index}
index={index}
data={project}
/>
);
}
return null;
})}
</InfiniteScroll>
<Motion
defaultStyle={{ transition: 0 }}
Expand All @@ -50,6 +57,7 @@ const Index = ({ dispatch, projects }) => (

const mapStateToProps = (state) => ({
projects: state.projects,
filter: state.projects.filter,
});

export default connect(mapStateToProps)(Index);
2 changes: 1 addition & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3312,7 +3312,7 @@ lodash.uniq@^4.3.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"

"lodash@>=3.5 <5", lodash@^4.0.0, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.16.2, lodash@^4.16.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0:
"lodash@>=3.5 <5", lodash@^4.0.0, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.16.2, lodash@^4.16.4, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0:
version "4.17.4"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"

Expand Down

0 comments on commit d6cc55a

Please sign in to comment.