Entony 6 éve
szülő
commit
7c8e14a883

+ 5 - 0
package-lock.json

@@ -11757,6 +11757,11 @@
         "symbol-observable": "^1.2.0"
       }
     },
+    "redux-thunk": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz",
+      "integrity": "sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw=="
+    },
     "regenerate": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz",

+ 2 - 1
package.json

@@ -8,7 +8,8 @@
     "react-redux": "^5.1.1",
     "react-router-dom": "^4.3.1",
     "react-scripts": "2.1.1",
-    "redux": "^4.0.1"
+    "redux": "^4.0.1",
+    "redux-thunk": "^2.3.0"
   },
   "scripts": {
     "start": "react-scripts start",

+ 4 - 2
src/Reducers/index.js

@@ -1,7 +1,9 @@
 import { combineReducers } from "redux";
 
-import test1 from "./test1";
+import todo from "./todo";
+import weather from "./weather";
 
 export default combineReducers({
-	test1
+	todo,
+	w: weather
 });

+ 64 - 0
src/Reducers/todo.js

@@ -0,0 +1,64 @@
+import * as types from "../constants/actionTypes";
+
+const initState = {
+	inputData: "",
+	list: []
+};
+
+export default (state = initState, { type, payload }) => {
+	switch (type) {
+		case types.CHANGE_INPUT_VALUE: {
+			return {
+				...state,
+				inputData: payload
+			};
+		}
+		case types.ADD_TO_LIST: {
+			const newData = {
+				value: state.inputData,
+				edit: false,
+				id: new Date().getTime()
+			};
+
+			return {
+				...state,
+				inputData: "",
+				list: state.list.concat(newData)
+			};
+		}
+		case types.TOGGLE_EDIT_FIELD: {
+			console.log("TOGGLE_EDIT_FIELD", payload);
+
+			const list = state.list.map(el => (el.id === payload ? { ...el, edit: !el.edit } : el));
+
+			// const list = state.list.map(el => {
+			// 	if(el.id === payload) {
+			// 		return {...el, edit: !el.edit}
+			// 	} else {
+			// 		return el
+			// 	}
+			// })
+
+			return {
+				...state,
+				list
+			};
+		}
+
+		case types.CHANGE_LIST_VALUE: {
+			const { id, value } = payload;
+			const list = state.list.map(el => (el.id === id ? { ...el, value: value } : el));
+
+			return { ...state, list };
+		}
+
+		case types.DELETE_ITEM_LIST: {
+			const list = state.list.filter(el => el.id !== payload);
+
+			return { ...state, list };
+		}
+
+		default:
+			return state;
+	}
+};

+ 15 - 19
src/Reducers/test1.js

@@ -1,46 +1,42 @@
 import * as types from "../constants/actionTypes";
 
 const initState = {
-	dataFetch: [],
-	title: "",
-	cuntry: ""
+	city: "",
+	weather: null,
+	isFetching: false,
+	error: null
 };
 
 export default (state = initState, { type, payload }) => {
 	switch (type) {
-		case types.ADD: {
+		case types.WEATHER_REQUEST: {
 			return {
 				...state,
-				count: state.count + 1
+				isFetching: true
 			};
 		}
-		case types.DEC: {
+		case types.WEATHER_REQUEST_SUCCESS: {
+			const { channel } = payload.query.results;
 			return {
 				...state,
-				count: state.count - 1
+				isFetching: false,
+				weather: channel
 			};
 		}
-
-		case types.REQUEST: {
+		case types.WEATHER_REQUEST_FAIL: {
 			return {
 				...state,
-				isFetching: true
+				isFetching: false,
+				error: "ERROR"
 			};
 		}
-		case types.REQUEST_SUCCESS: {
+		case types.TAKE_INPUT_VALUE: {
 			return {
 				...state,
-				data: "tony",
-				isFetching: false
+				city: payload
 			};
 		}
 
-		case types.REQUEST_FAIL: {
-			return {
-				...state,
-				isFetching: false
-			};
-		}
 		default:
 			return state;
 	}

+ 0 - 36
src/actions/test1.js

@@ -1,36 +0,0 @@
-import * as types from "../constants/actionTypes";
-
-export const add = payload => ({
-	type: types.ADD,
-	payload
-});
-
-export const dec = payload => ({
-	type: types.DEC,
-	payload
-});
-
-const request = payload => ({
-	type: types.REQUEST,
-	payload
-});
-
-const requestOk = payload => ({
-	type: types.REQUEST_SUCCESS,
-	payload
-});
-
-const requestFail = payload => ({
-	type: types.REQUEST_FAIL,
-	payload
-});
-
-// export const requestGO = payload => {
-// 	return dispatch => {
-// 		dispatch(request());
-// 		return fetch
-// 			.get()
-// 			.then(response => dispatch(requestOk(response)))
-// 			.catch(err => dispatch(requestFail(err)));
-// 	};
-// };

+ 26 - 0
src/actions/todo.js

@@ -0,0 +1,26 @@
+import * as types from "../constants/actionTypes";
+
+export const changeInputValue = payload => ({
+	type: types.CHANGE_INPUT_VALUE,
+	payload
+});
+
+export const addToList = payload => ({
+	type: types.ADD_TO_LIST,
+	payload
+});
+
+export const toggleEditField = payload => ({
+	type: types.TOGGLE_EDIT_FIELD,
+	payload
+});
+
+export const changelistValue = payload => ({
+	type: types.CHANGE_LIST_VALUE,
+	payload
+});
+
+export const deleteItemList = payload => ({
+	type: types.DELETE_ITEM_LIST,
+	payload
+});

+ 35 - 0
src/actions/weather.js

@@ -0,0 +1,35 @@
+import * as types from "../constants/actionTypes";
+
+const weatherRequest = payload => ({
+	type: types.WEATHER_REQUEST,
+	payload
+});
+
+const weatherRequestSuccess = payload => ({
+	type: types.WEATHER_REQUEST_SUCCESS,
+	payload
+});
+
+const weatherRequestFail = payload => ({
+	type: types.WEATHER_REQUEST_FAIL,
+	payload
+});
+
+export const takeInputValue = payload => ({
+	type: types.TAKE_INPUT_VALUE,
+	payload
+});
+
+export const getWeather = payload => {
+	return dispatch => {
+		dispatch(weatherRequest());
+		return fetch(
+			`https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22${payload}%2C%20ak%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys`
+		)
+			.then(response => response.json())
+			.then(res => {
+				dispatch(weatherRequestSuccess(res));
+			})
+			.catch(err => dispatch(weatherRequestFail(err)));
+	};
+};

+ 25 - 0
src/components/form/index.js

@@ -0,0 +1,25 @@
+import React, { Component } from "react";
+
+export default class Form extends Component {
+	submit = () => {
+		const { addToList } = this.props;
+		addToList();
+	};
+
+	handleChange = e => {
+		const { changeInputValue } = this.props;
+		changeInputValue(e.target.value);
+	};
+
+	render() {
+		const { inputData } = this.props;
+		return (
+			<div>
+				<input type="text" value={inputData} onChange={this.handleChange} />
+				<button type="submit" onClick={this.submit}>
+					LETS GO
+				</button>
+			</div>
+		);
+	}
+}

+ 11 - 0
src/components/header/index.js

@@ -0,0 +1,11 @@
+import React from "react";
+import { Link } from "react-router-dom";
+
+export default () => (
+	<header>
+		<nav>
+			<Link to="/">home</Link>
+			<Link to="/fetch">fetch</Link>
+		</nav>
+	</header>
+);

+ 0 - 14
src/components/home-page/index.js

@@ -1,14 +0,0 @@
-import React, { Component } from "react";
-
-export default class Homopage extends Component {
-	render() {
-		const { add, dec } = this.props;
-		return (
-			<div>
-				Hello I am Home page
-				<button onClick={add}>+</button>
-				<button onClick={dec}>-</button>
-			</div>
-		);
-	}
-}

+ 41 - 0
src/components/list/index.js

@@ -0,0 +1,41 @@
+import React, { Component } from "react";
+
+export default class List extends Component {
+	change = ({ id, value }) => {
+		const { changelistValue } = this.props;
+		changelistValue({ id, value });
+	};
+
+	deleteItem = (e, id) => {
+		e.stopPropagation();
+		const { deleteItemList } = this.props;
+		deleteItemList(id);
+	};
+
+	render() {
+		const { list, toggleEditField } = this.props;
+		return (
+			<div>
+				<ul>
+					{list.map(el =>
+						el.edit ? (
+							<div key={el.id}>
+								<input
+									type="text"
+									value={el.value}
+									onChange={e => this.change({ id: el.id, value: e.target.value })}
+								/>
+								<button onClick={toggleEditField.bind(null, el.id)}>SAVE MEEEEE</button>
+							</div>
+						) : (
+							<li onClick={toggleEditField.bind(null, el.id)} key={el.id}>
+								{el.value}
+								<button onClick={e => this.deleteItem(e, el.id)}>x</button>
+							</li>
+						)
+					)}
+				</ul>
+			</div>
+		);
+	}
+}

+ 31 - 0
src/components/page/index.js

@@ -0,0 +1,31 @@
+import React, { Component } from "react";
+
+import List from "../list";
+import Form from "../form";
+import "./style.css";
+
+export default class Page extends Component {
+	render() {
+		const {
+			list,
+			inputData,
+			addToList,
+			changeInputValue,
+			toggleEditField,
+			changelistValue,
+			deleteItemList
+		} = this.props;
+		console.log("list", list);
+		return (
+			<div className="container">
+				<Form changeInputValue={changeInputValue} addToList={addToList} inputData={inputData} />
+				<List
+					deleteItemList={deleteItemList}
+					changelistValue={changelistValue}
+					toggleEditField={toggleEditField}
+					list={list}
+				/>
+			</div>
+		);
+	}
+}

+ 3 - 0
src/components/page/style.css

@@ -0,0 +1,3 @@
+.container {
+	display: flex;
+}

+ 9 - 5
src/constants/actionTypes.js

@@ -1,6 +1,10 @@
-export const ADD = "ADD";
-export const DEC = "DEC";
+export const CHANGE_INPUT_VALUE = "CHANGE_INPUT_VALUE";
+export const ADD_TO_LIST = "ADD_TO_LIST";
+export const TOGGLE_EDIT_FIELD = "TOGGLE_EDIT_FIELD";
+export const CHANGE_LIST_VALUE = "CHANGE_LIST_VALUE";
+export const DELETE_ITEM_LIST = "DELETE_ITEM_LIST";
 
-export const REQUEST = "REQUEST";
-export const REQUEST_SUCCESS = "REQUEST_SUCCESS";
-export const REQUEST_FAIL = "REQUEST_FAIL";
+export const WEATHER_REQUEST = "WEATHER_REQUEST";
+export const WEATHER_REQUEST_SUCCESS = "WEATHER_REQUEST_SUCCESS";
+export const WEATHER_REQUEST_FAIL = "WEATHER_REQUEST_FAIL";
+export const TAKE_INPUT_VALUE = "TAKE_INPUT_VALUE";

+ 9 - 20
src/container/App.js

@@ -2,38 +2,27 @@ import React, { Component } from "react";
 import { bindActionCreators } from "redux";
 import { connect } from "react-redux";
 
-import HomePage from "../components/home-page";
-import { add, dec } from "../actions/test1";
-
-import logo from "./logo.svg";
-import "./App.css";
+import Page from "../components/page";
+import * as actions from "../actions/todo";
+import Header from "../components/header";
 
 class App extends Component {
 	render() {
-		const { counter, add, dec } = this.props;
-		console.log("erw", this.props);
 		return (
-			<div className="App">
-				<header className="App-header">
-					<img src={logo} className="App-logo" alt="logo" />
-					<p>
-						Edit <code>src/App.js</code> and save to reload.
-					</p>
-					<a className="App-link" href="https://reactjs.org" target="_blank" rel="noopener noreferrer">
-						Learn React {counter}
-					</a>
-				</header>
-				<HomePage dec={dec} add={add} />
+			<div>
+				<Header />
+				<Page {...this.props} />
 			</div>
 		);
 	}
 }
 
 const mapStateToProps = state => ({
-	counter: state.test1.count
+	inputData: state.todo.inputData,
+	list: state.todo.list
 });
 
-const mapDispatchToProps = dispatch => bindActionCreators({ add, dec }, dispatch);
+const mapDispatchToProps = dispatch => bindActionCreators({ ...actions }, dispatch);
 
 export default connect(
 	mapStateToProps,

+ 48 - 0
src/container/fetchPage.js

@@ -0,0 +1,48 @@
+import React, { Component } from "react";
+import { connect } from "react-redux";
+import { bindActionCreators } from "redux";
+
+import { takeInputValue, getWeather } from "../actions/weather";
+
+import Header from "../components/header";
+
+class FetchPage extends Component {
+	change = e => {
+		const { takeInputValue } = this.props;
+		takeInputValue(e.target.value);
+	};
+
+	click = () => {
+		const { city, getWeather } = this.props;
+		getWeather(city);
+	};
+
+	render() {
+		const { weather, error } = this.props;
+
+		return (
+			<div>
+				<Header />
+
+				<input type="text" onChange={this.change} />
+				<button onClick={this.click}>SHOW</button>
+
+				<div>{weather && weather.location && weather.location.city}</div>
+				<div>{error && error}</div>
+			</div>
+		);
+	}
+}
+
+const mapStateToProps = state => ({
+	city: state.w.city,
+	weather: state.w.weather,
+	error: state.w.error
+});
+
+const mapDispatchToProps = dispatch => bindActionCreators({ takeInputValue, getWeather }, dispatch);
+
+export default connect(
+	mapStateToProps,
+	mapDispatchToProps
+)(FetchPage);

+ 8 - 24
src/router.js

@@ -1,29 +1,13 @@
 import React from "react";
-import { Switch, Route, Link } from "react-router-dom";
+import { Switch, Route } from "react-router-dom";
 import App from "./container/App";
-import Test2 from "./container/test2";
+import FetchPage from "./container/fetchPage";
 
 export default () => (
-	<div>
-		<nav>
-			<ul>
-				<li>
-					<Link to="/">Home</Link>
-				</li>
-				<li>
-					<Link to="/about/">About</Link>
-				</li>
-				<li>
-					<Link to="/users/">Users</Link>
-				</li>
-			</ul>
-		</nav>
-		<Switch>
-			<div>
-				<Route path="/" exact component={App} />
-				<Route exact path="/about/" component={Test2} />
-				<Route exact path="/users/" render={() => <div>ololo</div>} />
-			</div>
-		</Switch>
-	</div>
+	<Switch>
+		<div>
+			<Route path="/" exact component={App} />
+			<Route exact path="/fetch" component={FetchPage} />
+		</div>
+	</Switch>
 );

+ 4 - 3
src/state/state.js

@@ -1,10 +1,11 @@
-import { createStore } from "redux";
+import { createStore, applyMiddleware } from "redux";
+import thunk from "redux-thunk";
 // import logger from "redux-logger";
 
 import reducers from "../Reducers";
 
 export default createStore(
-	reducers
+	reducers,
 	// composeEnhancers(applyMiddleware(logger, sagaMiddleware)),
-	// applyMiddleware(logger, sagaMiddleware)
+	applyMiddleware(thunk)
 );