add filters

This commit is contained in:
2018-05-11 14:41:26 +03:00
parent 5eead875d5
commit b0ff9e4c5d
9 changed files with 131 additions and 6 deletions

View File

@@ -14,5 +14,8 @@
"allowTernary": true
}
]
},
"env": {
"browser": true
}
}

View File

@@ -274,3 +274,27 @@ li:first-child .item {
max-height: 0;
}
}
.header {
display: flex;
justify-content: space-between;
}
.filters {
align-self: center;
margin-right: 2rem;
}
.filter {
margin: 0.1rem;
padding: 0.5rem;
color: gray;
border: none;
background: none;
transition: 0.1s ease-in-out;
font-size: 0.9rem;
}
.filter--active {
color: black;
}

View File

@@ -3,11 +3,12 @@ import "./App.css";
import InputContainer from "./containers/InputContainer";
import ItemsContainer from "./containers/ItemsContainer";
import Header from "./components/Header";
export default function App() {
return (
<div id="container">
<h1>To-Do List</h1>
<Header />
<InputContainer />
<ItemsContainer />
</div>

19
src/components/Header.js Normal file
View File

@@ -0,0 +1,19 @@
import React from "react";
import FilterLink from "../containers/FilterLink";
import { VisibilityFilters } from "../actions";
import "../App.css";
export default function Header() {
return (
<div className="header">
<h1>Todos</h1>
<div className="filters">
<FilterLink filter={VisibilityFilters.SHOW_ALL}>all</FilterLink>
<FilterLink filter={VisibilityFilters.SHOW_ACTIVE}>active</FilterLink>
<FilterLink filter={VisibilityFilters.SHOW_COMPLETED}>
completed
</FilterLink>
</div>
</div>
);
}

28
src/components/Link.js Normal file
View File

@@ -0,0 +1,28 @@
import React from "react";
import PropTypes from "prop-types";
import "../App.css";
export default function Link({ active, onClick, children }) {
const classes = ["filter"];
if (active) {
classes.push("filter--active");
}
return (
<button
className={classes.join(" ")}
onClick={e => {
e.preventDefault();
onClick();
}}
>
{children}
</button>
);
}
Link.propTypes = {
active: PropTypes.bool.isRequired,
onClick: PropTypes.func.isRequired,
children: PropTypes.node.isRequired
};

View File

@@ -0,0 +1,20 @@
import { connect } from "react-redux";
import Link from "../components/Link";
import { setVisibilityFilter } from "../actions";
function mapStateToProps(state, ownProps) {
return {
active: ownProps.filter === state.visibilityFilter
};
}
function mapDispatchToProps(dispatch, ownProps) {
return {
onClick: () => dispatch(setVisibilityFilter(ownProps.filter))
};
}
const FilterLink = connect(mapStateToProps, mapDispatchToProps)(Link);
export default FilterLink;

View File

@@ -3,7 +3,7 @@ import PropTypes from "prop-types";
import { connect } from "react-redux";
import Input from "../components/Input";
import { addItem } from "../actions";
import { addItem, VisibilityFilters } from "../actions";
const InputContainer = props => (
<Input
@@ -12,6 +12,19 @@ const InputContainer = props => (
/>
);
function getVisibleItems(items, filter) {
switch (filter) {
case VisibilityFilters.SHOW_ALL:
return items;
case VisibilityFilters.SHOW_ACTIVE:
return items.filter(item => !item.completed);
case VisibilityFilters.SHOW_COMPLETED:
return items.filter(item => item.completed);
default:
return items;
}
}
InputContainer.propTypes = {
inputBottomBorder: PropTypes.bool.isRequired,
dispatch: PropTypes.func.isRequired
@@ -19,7 +32,8 @@ InputContainer.propTypes = {
function mapStateToProps(state) {
return {
inputBottomBorder: state.items.length !== 0
inputBottomBorder:
getVisibleItems(state.items, state.visibilityFilter).length !== 0
};
}

View File

@@ -1,9 +1,25 @@
import { connect } from "react-redux";
import TodoList from "../components/TodoList";
import { toggleItem, reomveItem } from "../actions";
import { toggleItem, reomveItem, VisibilityFilters } from "../actions";
function getVisibleItems(items, filter) {
switch (filter) {
case VisibilityFilters.SHOW_ALL:
return items;
case VisibilityFilters.SHOW_ACTIVE:
return items.filter(item => !item.completed);
case VisibilityFilters.SHOW_COMPLETED:
return items.filter(item => item.completed);
default:
return items;
}
}
function mapStateToProps(state) {
return state;
console.log(state.visibilityFilter);
return {
items: getVisibleItems(state.items, state.visibilityFilter)
};
}
function mapDispatchToProps(dispatch) {

View File

@@ -5,7 +5,7 @@ const { SHOW_ALL } = VisibilityFilters;
export default function visibilityFilter(state = SHOW_ALL, action) {
switch (action.type) {
case SET_VISIBILITY_FILTER:
return { ...state, visibilityFilter: action.filter };
return action.filter;
default:
return state;
}