Browse Source

add redux todo

Entony 5 years ago
parent
commit
d5178034a6

+ 10 - 0
src/actionTypes/actionTypes.js

@@ -4,3 +4,13 @@ export const DECREASE = "DECREASE";
 export const REQUEST = "REQUEST";
 export const REQUEST_SUCCESS = "REQUEST_SUCCESS";
 export const REQUEST_FAIL = "REQUEST_FAIL";
+
+export const HANDLE_CHANGE_EVENT = "HANDLE_CHANGE_EVENT";
+export const RESET_FORM = "RESET_FORM";
+export const HANDLE_SUBMIT_EVENT = "HANDLE_SUBMIT_EVENT";
+export const REMOVE_ITEM = "REMOVE_ITEM";
+export const EDIT_ITEM = "EDIT_ITEM";
+export const SUBMIT_HANDLER_EDIT = "SUBMIT_HANDLER_EDIT";
+
+export const ADD_HOBBY = "ADD_HOBBY";
+export const REMOVE_HOBBY = "REMOVE_HOBBY";

+ 62 - 0
src/actions/redux-todo.js

@@ -0,0 +1,62 @@
+import {
+	HANDLE_CHANGE_EVENT,
+	RESET_FORM,
+	HANDLE_SUBMIT_EVENT,
+	ADD_HOBBY,
+	REMOVE_HOBBY,
+	REMOVE_ITEM,
+	EDIT_ITEM,
+	SUBMIT_HANDLER_EDIT
+} from "../actionTypes/actionTypes";
+
+export const handleChangeEvent = payload => {
+	return {
+		type: HANDLE_CHANGE_EVENT,
+		payload
+	};
+};
+
+export const resetForm = () => {
+	return {
+		type: RESET_FORM
+	};
+};
+
+export const handleSubmitEvent = () => {
+	return {
+		type: HANDLE_SUBMIT_EVENT
+	};
+};
+
+export const addHobby = () => {
+	return {
+		type: ADD_HOBBY
+	};
+};
+
+export const removeHobby = payload => {
+	return {
+		type: REMOVE_HOBBY,
+		payload
+	};
+};
+
+export const removeItem = payload => {
+	return {
+		type: REMOVE_ITEM,
+		payload
+	};
+};
+
+export const editItem = payload => {
+	return {
+		type: EDIT_ITEM,
+		payload
+	};
+};
+
+export const submitHandlerEdit = () => {
+	return {
+		type: SUBMIT_HANDLER_EDIT
+	};
+};

BIN
src/assets/img/karikatura_minon_19.jpg


+ 7 - 4
src/components/form/index.js

@@ -13,6 +13,9 @@ export default class Form extends Component {
 	render() {
 		const { values, onChangeEvent, reset, editableForm, addHobby, rmHobby } = this.props;
 
+		const disHobbyAdd = values.hobby.every(el => el.value);
+		const disHobbyRm = values.hobby.length === 1;
+
 		return (
 			<form onSubmit={this.submit}>
 				<Input
@@ -38,12 +41,12 @@ export default class Form extends Component {
 					name="editable"
 					label="Editable"
 				/>
-				<Button text="+" onClick={addHobby} />
+				<Button text="+" onClick={addHobby} disabled={!disHobbyAdd} />
 
-				{values.hobby.map(el => (
-					<div key={el.id}>
+				{values.hobby.map((el, i) => (
+					<div key={`${el.id}/${i}`}>
 						<Input onChange={onChangeEvent} value={el.value} id={el.id} name="hobby" label="Hobby" />
-						<Button text="-" onClick={rmHobby.bind(null, el.id)} />
+						{!disHobbyRm && <Button text="-" onClick={rmHobby.bind(null, el.id)} />}
 					</div>
 				))}
 

+ 5 - 1
src/components/header/index.js

@@ -1,7 +1,11 @@
 import React from "react";
 import { Link, withRouter } from "react-router-dom";
 
-const liArr = [{ path: "/", id: 1, text: "Main" }, { path: "/count", id: 2, text: "Counter from redux" }];
+const liArr = [
+	{ path: "/", id: 1, text: "Main" },
+	{ path: "/count", id: 2, text: "Counter from redux" },
+	{ path: "/redux-todo", id: 3, text: "Todo redux" }
+];
 
 const header = props => {
 	const event = () =>

+ 5 - 1
src/containers/count.js

@@ -1,11 +1,13 @@
 import React, { Component } from "react";
 import { connect } from "react-redux";
-import { bindActionCreators } from "redux";
+// import { bindActionCreators } from "redux";
 
 import Loader from "../components/HOC/loader";
 import { increase, decrease } from "../actions/todo";
 import { doRequest } from "../actions/request";
 
+import "./count.scss";
+
 export class Count extends Component {
 	componentDidMount() {
 		console.log("this.props", this.props);
@@ -31,6 +33,8 @@ export class Count extends Component {
 				</Loader>
 				<button onClick={() => increase(10)}>INC</button>
 				<button onClick={decrease}>DEC</button>
+
+				<div className="box-image" />
 			</div>
 		);
 	}

+ 6 - 0
src/containers/count.scss

@@ -0,0 +1,6 @@
+.box-image {
+	width: 200px;
+	height: 200px;
+	background-image: url("../assets/img/karikatura_minon_19.jpg");
+	background-size: cover;
+}

+ 25 - 4
src/containers/main.js

@@ -24,7 +24,14 @@ class Main extends Component {
 			firstName: "",
 			lastName: "",
 			age: "",
-			hobby: [{ id: new Date().getTime(), value: "" }]
+			hobby: [
+				{
+					id: Math.random()
+						.toString()
+						.substr(2, 100),
+					value: ""
+				}
+			]
 		}
 	};
 
@@ -33,7 +40,12 @@ class Main extends Component {
 			...prevState,
 			item: {
 				...prevState.item,
-				hobby: prevState.item.hobby.concat({ id: new Date().getTime(), value: "" })
+				hobby: prevState.item.hobby.concat({
+					id: Math.random()
+						.toString()
+						.substr(2, 100),
+					value: ""
+				})
 			}
 		}));
 	};
@@ -92,7 +104,9 @@ class Main extends Component {
 			...prevState,
 			list: prevState.list.concat({
 				...prevState.item,
-				id: new Date().getTime(),
+				id: Math.random()
+					.toString()
+					.substr(2, 100),
 				hobby: prevState.item.hobby.map(el => el.value)
 			})
 		}));
@@ -107,7 +121,14 @@ class Main extends Component {
 				firstName: "",
 				lastName: "",
 				age: "",
-				hobby: [{ id: new Date().getTime(), value: "" }]
+				hobby: [
+					{
+						id: Math.random()
+							.toString()
+							.substr(2, 100),
+						value: ""
+					}
+				]
 			},
 			editableForm: false
 		});

+ 79 - 0
src/containers/reduxTodo.js

@@ -0,0 +1,79 @@
+import React, { Component } from "react";
+import { connect } from "react-redux";
+import * as actions from "../actions/redux-todo";
+
+import Button from "../components/button/button";
+
+import Form from "../components/form";
+
+export class ReduxTodo extends Component {
+	render() {
+		const {
+			list,
+			item,
+			handleChangeEvent,
+			resetForm,
+			editableForm,
+			handleSubmitEvent,
+			addHobby,
+			removeHobby,
+			removeItem,
+			editItem,
+			submitHandlerEdit
+		} = this.props;
+		return (
+			<div
+				style={{
+					display: "flex"
+				}}>
+				<div className="list">
+					{list.map(el => (
+						<div className="list__item" key={el.id}>
+							<Button
+								text="x"
+								className="list__rm-btn"
+								// onClick={() => this.removeHandler(el.id)} />
+								onClick={removeItem.bind(null, el.id)}
+							/>
+							{el.editable && (
+								<Button text="edit" className="list__edit-btn" onClick={editItem.bind(null, el.id)} />
+							)}
+							<h4 className="list__item-title">
+								{el.firstName} {el.lastName}
+							</h4>
+							<p className="list__item-age">Age: {el.age}</p>
+							<ul className="list__item-ul">
+								{el.hobby.map(elem => (
+									<li className="list__item-li" key={elem}>
+										{elem}
+									</li>
+								))}
+							</ul>
+						</div>
+					))}
+				</div>
+
+				<Form
+					rmHobby={removeHobby}
+					addHobby={addHobby}
+					editableForm={editableForm}
+					reset={resetForm}
+					onChangeEvent={handleChangeEvent}
+					onSubmitEvent={editableForm ? submitHandlerEdit : handleSubmitEvent}
+					values={item}
+				/>
+			</div>
+		);
+	}
+}
+
+const mapStateToProps = state => ({
+	list: state.redux_todo.list,
+	item: state.redux_todo.item,
+	editableForm: state.redux_todo.editableForm
+});
+
+export default connect(
+	mapStateToProps,
+	{ ...actions }
+)(ReduxTodo);

+ 3 - 1
src/reducer/index.js

@@ -2,8 +2,10 @@ import { combineReducers } from "redux";
 
 import counter from "./todo";
 import request from "./request";
+import redux_todo from "./redux-todo";
 
 export default combineReducers({
 	counter,
-	request
+	request,
+	redux_todo
 });

+ 150 - 0
src/reducer/redux-todo.js

@@ -0,0 +1,150 @@
+import {
+	HANDLE_CHANGE_EVENT,
+	RESET_FORM,
+	HANDLE_SUBMIT_EVENT,
+	ADD_HOBBY,
+	REMOVE_HOBBY,
+	REMOVE_ITEM,
+	EDIT_ITEM,
+	SUBMIT_HANDLER_EDIT
+} from "../actionTypes/actionTypes";
+
+const list = [
+	{
+		id: 1,
+		editable: true,
+		firstName: "Tony",
+		lastName: "Montana",
+		age: 50,
+		hobby: ["drugs", "guns"]
+	}
+];
+
+const initialValue = {
+	list: list,
+	editableForm: false,
+	item: {
+		editable: false,
+		firstName: "",
+		lastName: "",
+		age: "",
+		hobby: [
+			{
+				id: Math.random()
+					.toString()
+					.substr(2, 100),
+				value: ""
+			}
+		]
+	}
+};
+
+export default (state = initialValue, action) => {
+	switch (action.type) {
+		case HANDLE_CHANGE_EVENT: {
+			const { name, value, checked, type, id } = action.payload.target;
+
+			if (name === "hobby") {
+				return {
+					...state,
+					item: {
+						...state.item,
+						hobby: state.item.hobby.map(el => (el.id === id ? { ...el, value } : el))
+					}
+				};
+			}
+
+			return {
+				...state,
+				item: {
+					...state.item,
+					[name]: type === "checkbox" ? checked : value
+				}
+			};
+		}
+
+		case RESET_FORM: {
+			return { ...state, editableForm: initialValue.editableForm, item: initialValue.item };
+		}
+
+		case HANDLE_SUBMIT_EVENT: {
+			return {
+				...state,
+				list: state.list.concat({
+					...state.item,
+					id: Math.random()
+						.toString()
+						.substr(2, 100),
+					hobby: state.item.hobby.filter(el => el.value).map(el => el.value)
+				}),
+				editableForm: initialValue.editableForm,
+				item: initialValue.item
+			};
+		}
+
+		case ADD_HOBBY: {
+			return {
+				...state,
+				item: {
+					...state.item,
+					hobby: state.item.hobby.concat({
+						id: Math.random()
+							.toString()
+							.substr(2, 100),
+						value: ""
+					})
+				}
+			};
+		}
+
+		case REMOVE_HOBBY: {
+			return {
+				...state,
+				item: {
+					...state.item,
+					hobby: state.item.hobby.filter(el => el.id !== action.payload)
+				}
+			};
+		}
+
+		case REMOVE_ITEM: {
+			return {
+				...state,
+				list: state.list.filter(el => el.id !== action.payload)
+			};
+		}
+
+		case EDIT_ITEM: {
+			const item = state.list.find(el => el.id === action.payload);
+			return {
+				...state,
+				item: {
+					...item,
+					hobby: item.hobby.map(el => ({
+						id: Math.random()
+							.toString()
+							.substr(2, 100),
+						value: el
+					}))
+				},
+				editableForm: true
+			};
+		}
+
+		case SUBMIT_HANDLER_EDIT: {
+			return {
+				...state,
+				list: state.list.map(el =>
+					el.id === state.item.id
+						? { ...state.item, hobby: state.item.hobby.filter(el => el.value).map(el => el.value) }
+						: el
+				),
+				editableForm: initialValue.editableForm,
+				item: initialValue.item
+			};
+		}
+
+		default:
+			return state;
+	}
+};

+ 3 - 0
src/router.js

@@ -3,11 +3,14 @@ import { Switch, Route, Redirect } from "react-router-dom";
 
 import Main from "./containers/main";
 import Count from "./containers/count";
+import ReduxTodo from "./containers/reduxTodo";
 
 export default () => (
 	<Switch>
 		<Route exact path="/" component={Main} />
 		<Route exact path="/count" component={Count} />
+		<Route exact path="/todo" component={Count} />
+		<Route exact path="/redux-todo" component={ReduxTodo} />
 
 		<Route
 			exact