· 6 years ago · Nov 21, 2019, 01:56 AM
1// ROOT.JSX
2
3import React from "react";
4import { connect } from "react-redux";
5import { ItemAction } from "../actions/ItemAction";
6import { AddToCartAction } from "../actions/OrderAction";
7import { ItemsList } from "../components/ItemsList";
8import { SearchItems } from "../actions/SearchAction";
9import _ from 'underscore';
10/** * Call the Item action function.
11* @param dispatch
12* @returns {{ItemAction: (function()), AddToCartAction: (function(*=))}}
13*/
14const mapDispatchToProps = (dispatch) => {
15 return {
16 ItemAction: () => {
17 return dispatch(ItemAction());
18 },
19 AddToCartAction: (cartData) => {
20 return dispatch(AddToCartAction(cartData));
21 },
22 SearchItems: (formData) => {
23 //TODO-4 : TODO-4 attach the props and dispatcher to Search component.
24 dispatch(SearchItems(formData));
25 }
26 };
27};
28/** * Get the restaurant data and order success message from reducer.
29* @param state
30* @returns {{items: (*|string|DataTransferItemList), message}}
31*/
32const mapStateToProps = (state) => {
33 //TODO-4 : TODO-4 attach the props(items , message) and dispatcher to Search component.
34 return { items: state.items, message: state.message }
35};
36/** * Root Class */
37class Root extends React.Component {
38 /** * Constructor * @param props */
39 constructor(props) {
40 super(props);
41 this.state = {
42 checkedValue: [], loading: true, isChecked: [], name: "", city: "",
43 cuisine: "", budget: "", sortBy: "",
44 };
45 /** * Call ItemAction Action function. */
46 this.props.ItemAction();
47 };
48 /** * Search restaurant on the basis of search text. * @param event */
49 search = (event) => {
50 // TODO-7 - Prevent the event and call the Search Item action with appropriate state object.
51 event.preventDefault();
52 this.props.SearchItems(this.state);
53 };
54 /** * Set the search text data into the state object * @param event */
55 searchByText = (event) => {
56 //TODO-8 set the search text into the state object from event target object.
57 this.state[event.target.name] = event.target.value;
58 this.setState(this.state);
59 };
60 /** * Filter the restaurant search data on to the basis of different filter. * @param event */
61 filter = (event) => {
62 // TODO-6 set the filter option into the state object from event target object and call the Search item object.
63 this.state[event.target.name] = event.target.value;
64 this.setState(this.state);
65 this.props.SearchItems(this.state);
66 };
67 /** * Set the loading false When DOM update */
68 componentDidUpdate() {
69 setTimeout(() => this.setState({ loading: false }), 500);
70 };
71 /** * add the order into the AddToCart * @param id * @param name * @param isChecked */
72 addToCart = (id, name, isChecked) => {
73 if (isChecked) {
74 //TODO -10 Add the data in the format of "id"+"-"+"name" into the state checkedValue array.
75 this.state.checkedValue.push(id + "-" + name)
76 } else {
77 //TODO -11 remove the data in the format of "id"+"-"+"name" from the state checkedValue array.
78 let index = this.state.checkedValue.indexOf(id + "-" + name);
79 if (index > -1) {
80 this.state.checkedValue.splice(index, 1);
81 }
82 }
83 };
84 /** * Select the item for order * @param e * @param id * @param name */
85 selectItem = (e, id, name, key) => {
86 // TODO-1 Add the functionality to check the checkbox via setting state target name
87 // TODO-2 Call the addToCart Props function with id, name and checked or unchecked
88 var isChecked = this.state.isChecked;
89 isChecked[key] = !!isChecked[key] ? false : true;
90 this.setState({ isChecked });
91 this.addToCart(id, name, isChecked[key]);
92 };
93 /** * Handle the order submit action */
94 handleSubmit = () => {
95 if (!_.isEmpty(this.state.checkedValue)) {
96 //TODO-12 Call the addToCart props dispatch action and handle the promise object to display the popup message into the below format /** alert("Below Restaurant Order created successfully" + "\n" + this.state.checkedValue.map(function(i) { return i.split("-")[1] }));**/ //and catch the error if present
97 console.log(this.state.checkedValue);
98 this.props.AddToCartAction(this.state.checkedValue).then((response) => {
99 alert("Below Restaurant Order created successfully" + "\n" + this.state.checkedValue.map(function (i) {
100 return i.split("-")[1]
101 }));
102 }).catch(err => {
103 alert("Error in Catch \n" + err);
104 });
105 } else {
106 alert('Please select at least one item');
107 }
108 };
109 /** * Render the restaurant list data * @returns {*} */
110 render() {
111 const { loading } = this.state;
112 if (loading) {
113 return null; // render null when app is not ready
114 }
115 return (<ItemsList
116 items={this.props.items}
117 handleSubmit={this.handleSubmit}
118 search={this.search}
119 searchByText={this.searchByText}
120 filter={this.filter}
121 state={this.state}
122 selectItem={this.selectItem}
123 />);
124 }
125}
126
127
128/** * attach both Reducer and Action into the Root Container. */
129export default connect(mapStateToProps, mapDispatchToProps)(Root);
130// SEARCH ACTION
131
132import fetch from 'isomorphic-fetch';
133import { RESOURCE_URL, SEARCH_DATA } from '../constants/ActionTypes';
134/** * Search action to send data from action to your store, When action will dispatch,the state will update immediately.
135* It will hit the Get 'Restaurants' rest api to get restaurants data on to the basis of filters.
136* @returns {function(*)} * @constructor */
137export function SearchItems(searchParams) {
138 return dispatch => {
139 let filter = {};
140 searchParams.name ? (filter['name'] = searchParams.name) : '';
141 searchParams.city ? (filter['city'] = searchParams.city.trim()) : '';
142 searchParams.cuisine ? (filter['category'] = [searchParams.cuisine.trim()]) : [];
143 searchParams.sortBy ? (filter['sort'] = searchParams.sortBy.trim()) : 'asc';
144 searchParams.budget ? (filter['amount'] = searchParams.budget.trim()) : '';
145 // TODO-8.1- > Call the search filter api with the help of fetch module call that is given below into the TODO section and return the promise object as similar to other Action call.
146 return fetch(RESOURCE_URL + '/search?filter=' + JSON.stringify(filter), {
147 method: 'GET',
148 headers: {
149 'Accept': 'application/json',
150 'Content-Type': 'application/json'
151 }
152 }).then(response => {
153 if (response.status >= 200 && response.status < 300) {
154 return response.json();
155 } else {
156 const error = new Error(response.statusText);
157 error.response = response;
158 throw error;
159 }
160 }).then(json => dispatch({
161 type: SEARCH_DATA,
162 payload: json.restaurant
163 })).catch(error => {
164 console.log('request failed', error)
165 });
166 }
167}