Browse Source

Reorganize rootState. Add CreateRecipe reducer

Tatiana Inama 7 năm trước cách đây
mục cha
commit
7dc05a02f0

+ 44 - 0
recipes/src/containers/Recipes/Create/actions.ts

@@ -0,0 +1,44 @@
+import Recipe from 'types/recipes';
+import { scrapeRecipe as Scrape } from '../services';
+import { SCRAPE_RECIPE, RECEIVE_SCRAPE, INVALID_SCRAPE } from './types';
+
+const scrapeRecipe = (url: string) => ({
+  type: SCRAPE_RECIPE,
+  scrape: url,
+  fromScrape: true,
+  isFetching: true,
+  didInvalidate: false,
+});
+
+const receiveScrape = (json: Recipe) => ({
+  type: RECEIVE_SCRAPE,
+  isFetching: false,
+  didInvalidate: false,
+  initialState: json,
+  data: json,
+});
+
+const invalidateScrape = (error: any) => ({
+  type: INVALID_SCRAPE,
+  fromScrape: false,
+  isFetching: false,
+  didInvalidate: true,
+  error,
+});
+
+const fetchScrape = (url: string) => (dispatch: any) => {
+  dispatch(scrapeRecipe(url));
+  return Scrape(url)
+    .then(data => dispatch(receiveScrape(data)))
+    .catch(error => invalidateScrape(error))
+}
+
+export {
+  SCRAPE_RECIPE,
+  RECEIVE_SCRAPE,
+  INVALID_SCRAPE,
+  scrapeRecipe,
+  receiveScrape,
+  invalidateScrape,
+  fetchScrape,
+}

+ 2 - 2
recipes/src/containers/Recipes/Create.tsx

@@ -10,9 +10,9 @@ import { Form as IngredientForm } from 'components/Ingredient';
 
 import './styles.scss';
 
-import { scrapeRecipe } from './services';
+import { scrapeRecipe } from './../services';
 
-import sample_img from "../../sample.png";
+import sample_img from "../../../sample.png";
 import Recipe, { SubRecipe, Author, Details, _recipe, _subRecipe, _ingredient, Ingredient, Suggestion } from 'types/recipes';
 
 type CreateRecipeProps = {

+ 41 - 0
recipes/src/containers/Recipes/Create/reducers.ts

@@ -0,0 +1,41 @@
+import { FormState, FormActionTypes, SCRAPE_RECIPE, RECEIVE_SCRAPE, INVALID_SCRAPE } from './types';
+
+const initialState: FormState = {
+  data: {},
+  initialState: {},
+  fromScrape: false,
+  fetchingScrape: false,
+  invalidScrape: false,
+};
+
+export const createReducer = (
+  state = initialState,
+  action: FormActionTypes
+): FormState => {
+  switch (action.type) {
+    case SCRAPE_RECIPE:
+      return {
+        ...state,
+        fromScrape: true,
+        fetchingScrape: true,
+        invalidScrape: false,
+      }
+    case RECEIVE_SCRAPE:
+      return {
+        ...state,
+        fetchingScrape: false,
+        data: action.data,
+        initialState: action.data,
+        invalidScrape: false,
+      }
+    case INVALID_SCRAPE:
+      return {
+        ...state,
+        fetchingScrape: false,
+        invalidScrape: true,
+        fromScrape: false
+      }
+    default:
+      return state
+  }
+};

recipes/src/containers/Recipes/styles.scss → recipes/src/containers/Recipes/Create/styles.scss


+ 44 - 0
recipes/src/containers/Recipes/Create/types.ts

@@ -0,0 +1,44 @@
+import Recipe from "src/types/recipes";
+
+export const SCRAPE_RECIPE = 'SCRAPE_RECIPE';
+export const RECEIVE_SCRAPE = 'RECEIVE_SCRAPE';
+export const INVALID_SCRAPE = 'INVALID_SCRAPE';
+export const UPDATE_FIELD = 'UPDATE_FIELD';
+export const ADD_SUBRECIPE = 'ADD_SUBRECIPE';
+export const REMOVE_SUBRECIPE = 'REMOVE_SUBRECIPE';
+export const ADD_INGREDIENT = 'ADD_INGREDIENT';
+export const REMOVE_INGREDIENT = 'REMOVE_INGREDIENT';
+export const ADD_SUGGESTION = 'ADD_SUGGESTION';
+export const SELECT_SUGGESTION = 'SELECT_SUGGESTION';
+
+interface ScrapeRecipeAction {
+  type: typeof SCRAPE_RECIPE,
+  scrape: string,
+  fromScrape: boolean,
+  fetchingScrape: boolean,
+  invalidScrape: boolean,
+}
+
+interface ReceiveScrapeAction {
+  type: typeof RECEIVE_SCRAPE,
+  fetchingScrape: boolean,
+  invalidScrape: boolean,
+  initialState: Recipe,
+  data: Recipe,
+}
+
+interface InvalidScrapeAction {
+  type: typeof INVALID_SCRAPE,
+  fetchingScrape: boolean,
+  invalidScrape: boolean,
+}
+
+export interface FormState {
+  data: Recipe|{},
+  initialState: Recipe|{},
+  fromScrape: boolean,
+  fetchingScrape: boolean,
+  invalidScrape: boolean
+}
+
+export type FormActionTypes = ScrapeRecipeAction | ReceiveScrapeAction | InvalidScrapeAction;

+ 1 - 1
recipes/src/containers/Recipes/List/index.tsx

@@ -103,7 +103,7 @@ class RecipeList extends Component<RecipeListProps> {
 }
 
 const mapStateToProps = ({ recipes }: any, ownProps: any) => {
-  return recipes;
+  return recipes.list;
 }
 
 const mapDispatchToProps = (dispatch: any) => {

+ 7 - 18
recipes/src/containers/Recipes/List/reducers.ts

@@ -1,9 +1,7 @@
 const initialState = {
-  recipes: {
-    isFetching: false,
-    data: [],
-    selectedRecipe: undefined,
-  }
+  isFetching: false,
+  data: [],
+  selectedRecipe: undefined,
 };
 
 export const recipesReducer = (
@@ -14,27 +12,18 @@ export const recipesReducer = (
     case 'REQUEST_RECIPES': 
       return {
         ...state,
-        recipes: {
-          ...state.recipes,
-          isFetching: action.isFetching,
-        }
+        isFetching: action.isFetching,
       }
     case 'RECEIVE_RECIPES':
       return {
         ...state,
-        recipes: {
-          ...state.recipes,
-          isFetching: action.isFetching,
-          data: action.payload || state.recipes.data,
-        }
+        isFetching: action.isFetching,
+        data: action.payload || state.data,
       }
     case 'SELECT_RECIPE':
       return {
         ...state,
-        recipes: {
-          ...state.recipes,
-          selectedRecipe: action.payload
-        }
+        selectedRecipe: action.payload
       }
     default:
       return state;

+ 9 - 2
recipes/src/store/configureStore.ts

@@ -1,13 +1,20 @@
-import { createStore, applyMiddleware } from 'redux';
+import { createStore, applyMiddleware, combineReducers } from 'redux';
 import thunk from 'redux-thunk';
 import { composeWithDevTools } from 'redux-devtools-extension';
 import { recipesReducer } from 'containers/Recipes/List/reducers';
+import { createReducer } from 'containers/Recipes/Create/reducers';
 
 const composeEnhancers = composeWithDevTools({});
+const rootReducer = combineReducers({
+  recipes: combineReducers({
+    list: recipesReducer,
+    create: createReducer
+  })
+})
 
 const configureStore = () => {
   return createStore(
-    recipesReducer,
+    rootReducer,
     undefined,
     composeEnhancers(
       applyMiddleware(thunk)