Skip to content

Commit

Permalink
Merge pull request #23 from MarcoEscaleira/Redux_integration
Browse files Browse the repository at this point in the history
Redux integration
  • Loading branch information
MarcoEscaleira authored Mar 10, 2019
2 parents d6b1da1 + d0a0966 commit ae0ff39
Show file tree
Hide file tree
Showing 13 changed files with 334 additions and 137 deletions.
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@
"normalize.css": "^8.0.1",
"react": "^16.7.0",
"react-dom": "^16.7.0",
"react-redux": "^6.0.1",
"react-router": "^4.3.1",
"react-router-dom": "^4.3.1"
"react-router-dom": "^4.3.1",
"redux": "^4.0.1",
"redux-thunk": "^2.3.0",
"prop-types": "latest"
},
"devDependencies": {
"react-scripts": "2.1.3"
Expand Down
19 changes: 15 additions & 4 deletions src/components/Answer.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import React from 'react'
import PropTypes from 'prop-types';
import {connect} from "react-redux";
import {actions} from "../store/decisions";

const Answer = ({handleData, data: {msg, img}}) => (

const Answer = ({handleState, data: {msg, img}}) => (
<div className="answer">
<h1 className="answer__title">{ (msg === 'loading') ? "Loading" : msg }</h1>
<img
Expand All @@ -10,7 +13,7 @@ const Answer = ({handleData, data: {msg, img}}) => (
className="answer__image"
/>
<button
onClick={handleData}
onClick={handleState}
className="answer__btn"
>
Clean
Expand All @@ -19,8 +22,16 @@ const Answer = ({handleData, data: {msg, img}}) => (
);

Answer.propTypes = {
handleData: PropTypes.func,
handleState: PropTypes.func,
data: PropTypes.object
};

export default Answer;
const mapStateToProps = state => ({
data: state.data
});

const mapDispatchToProps = {
handleState: actions.resetState
};

export default connect(mapStateToProps, mapDispatchToProps)(Answer);
19 changes: 15 additions & 4 deletions src/components/ErrorModal.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import React from 'react';
import PropTypes from 'prop-types';
import {connect} from "react-redux";
import {actions} from "../store/decisions";

const ErrorModal = ({ show, text, closeCallback}) => (
const ErrorModal = ({ show, text, closeTypeError}) => (
<div className={`modal ${!show ? 'modal--invisible' : ''}`}>
<div className="modal__overlay" onClick={closeCallback}>
<div className="modal__overlay" onClick={closeTypeError}>
<div className="modal__content">
<h3 className="modal__title">Error</h3>
<p className="modal__body">{text}</p>
<button
className="modal__button"
onClick={closeCallback}
onClick={closeTypeError}
>
Okay
</button>
Expand All @@ -24,4 +26,13 @@ ErrorModal.propTypes = {
closeCallback: PropTypes.func
};

export default ErrorModal;
const mapStateToProps = state => ({
show: state.typeError.showModal,
text: state.typeError.text
});

const mapDispatchToProps = {
closeTypeError: actions.closeTypeError
};

export default connect(mapStateToProps, mapDispatchToProps)(ErrorModal);
113 changes: 87 additions & 26 deletions src/components/Form.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,95 @@
import React from 'react';
import PropTypes from 'prop-types';
import {connect} from "react-redux";
import {actions} from "../store/decisions";
import {API_URL} from "../config";

const Form = (props) => (
<div className="questionForm">
<h1 className="questionForm__title">What do you want to do?</h1>
<form
className="questionForm__form"
onSubmit={props.handleFormSubmit}
autoComplete="off"
>
<input
type="text"
name="toDo"
value={props.text}
onChange={props.handleTextInput}
className="questionForm__form__input"
/>
<button
type="submit" className="questionForm__form__btn"
>
Decide
</button>
</form>
</div>
);

class Form extends React.Component {
handleFormSubmit = (e) => {
e.preventDefault();

this.props.resetData();

const inputText = e.target.toDo.value.trim();

// Check if input is empty
if (!inputText) {
this.props.resetData();
this.props.handleTypeError("Please enter what you want to do");
return;
}

// Check if input is same as before
if (this.props.oldTextInput === inputText) {
this.props.resetData();
this.props.handleTypeError("Please do another thing!");
return;
}

this.props.setLoadingAnimation();

const request = async () => {
const response = await fetch(`${API_URL}/?search=${inputText}`, {
headers: {
"Content-Type": "application/json",
}
});
const data = await response.json();

this.props.setData(data, inputText);
};
request();
};

handleTextInput = (e) => {
const textInput = e.target.value;
this.props.handleTextInput(textInput);
};

render() {
return (
<div className="questionForm">
<h1 className="questionForm__title">What do you want to do?</h1>
<form
className="questionForm__form"
onSubmit={this.handleFormSubmit}
autoComplete="off"
>
<input
type="text"
name="toDo"
value={this.props.textInput}
onChange={this.handleTextInput}
className="questionForm__form__input"
/>
<button
type="submit" className="questionForm__form__btn"
>
Decide
</button>
</form>
</div>
);
}
}

Form.propTypes = {
handleFormSubmit: PropTypes.func,
text: PropTypes.string,
textInput: PropTypes.string,
handleTextInput: PropTypes.func
};

export default Form;
const mapStateToProps = state => ({
textInput: state.textInput,
oldTextInput: state.oldTextInput
});

const mapDispatchToProps = {
handleTextInput: actions.handleTextInput,
resetData: actions.resetData,
handleTypeError: actions.handleTypeError,
setLoadingAnimation: actions.setLoadingAnimation,
setData: actions.setData
};

export default connect(mapStateToProps, mapDispatchToProps)(Form);
8 changes: 7 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import React from 'react';
import ReactDOM from 'react-dom';
import {Provider} from 'react-redux';
import store from './store';

import 'normalize.css';
import './styles/styles.scss';
import AppRouter from './routers/AppRouter';

ReactDOM.render(<AppRouter />, document.getElementById('root'));
ReactDOM.render((
<Provider store={store()}>
<AppRouter />
</Provider>
), document.getElementById('root'));
110 changes: 11 additions & 99 deletions src/pages/HomePage.js
Original file line number Diff line number Diff line change
@@ -1,118 +1,30 @@
import React, { Component, Fragment } from 'react';

import Form from '../components/Form';
import Answer from '../components/Answer';
import HistoryBoard from '../components/HistoryBoard';
import ErrorModal from '../components/ErrorModal';
import {API_URL} from "../config";
import {connect} from "react-redux";

const DEFAULT_STATE = {
print: false,
data: {},
oldTextInput: '',
textInput: '',
typeError: {
showModal: false,
text: ''
}
};

class Home extends Component {
state = {
...DEFAULT_STATE
};

handleFormSubmit = (e) => {
e.preventDefault();

this.handleData();

const inputText = e.target.toDo.value.trim();

// Check if input is empty
if (!inputText) {
this.handleData();
this.handleTypeError("Please enter what you want to do");
return;
}

// Check if input is same as before
if (this.state.oldTextInput === inputText) {
this.handleData();
this.handleTypeError("Please do another thing!");
return;
}

//Loading animation
this.setState(() => ({ print: true, data: {
"msg": "loading",
"img": "./gifs/Blocks-1s-200px.gif"
} }));

const request = async () => {
const response = await fetch(`${API_URL}/?search=${inputText}`, {
headers: {
"Content-Type": "application/json",
}
});
const data = await response.json();
this.setState(() => ({ print: true, data, oldTextInput: inputText }));
};
request();
};

handleState = () => this.setState(() => ({ ...DEFAULT_STATE }));

handleData = () => this.setState(() => ({
print: false,
data: {}
}));

handleTypeError = (text = '') => this.setState(() => ({
typeError: {
showModal: true,
text
}
}));

closeTypeError = () => this.setState(() => ({
typeError: {
showModal: false,
text: ''
}
}));

handleTextInput = (e) => {
const textInput = e.target.value;
if(!textInput || /^[a-z\d\-_\s]+$/i.test(textInput)) {
this.setState(() => ({ textInput }));
}
};

render() {
return (
<Fragment>
<div className="container">
<Form
handleFormSubmit={this.handleFormSubmit}
handleTextInput={this.handleTextInput}
text={this.state.textInput}
/>
{ this.state.print &&
<Answer
handleData={this.handleState}
data={this.state.data}
/>
<Form />
{ this.props.print &&
<Answer />
}
<HistoryBoard />
</div>
<ErrorModal
show={this.state.typeError.showModal}
text={this.state.typeError.text}
closeCallback= {this.closeTypeError}
/>
<ErrorModal />
</Fragment>
);
}
}

export default Home;
const mapStateToProps = state => ({
print: state.print
});

export default connect(mapStateToProps)(Home);
2 changes: 1 addition & 1 deletion src/routers/AppRouter.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const AppRouter = () => (
<Header />
<Switch>
<Route exact path="/" component={HomePage} />
<Route path="/gallery" component={GalleryPage} />
<Route exact path="/gallery" component={GalleryPage} />
<Route component={NotFound} />
</Switch>
<Footer />
Expand Down
Loading

0 comments on commit ae0ff39

Please sign in to comment.