Przeglądaj źródła

Delete recipe button on recipe list

Tatiana Inama 6 lat temu
rodzic
commit
479ef21e68

+ 50 - 1
recipes/src/containers/Recipes/List/actions.ts

@@ -1,11 +1,17 @@
+import { ThunkAction } from 'redux-thunk';
 import axios from 'axios';
 import axios from 'axios';
 import Recipe from 'types/recipes';
 import Recipe from 'types/recipes';
-import { getRecipes } from '../services';
+import { getRecipes, deleteRecipe } from '../services';
+import { Action, ActionCreator, Dispatch } from 'redux';
 
 
 export const RECEIVE_RECIPES = 'RECEIVE_RECIPES';
 export const RECEIVE_RECIPES = 'RECEIVE_RECIPES';
 export const REQUEST_RECIPES = 'REQUEST_RECIPES';
 export const REQUEST_RECIPES = 'REQUEST_RECIPES';
 export const SELECT_RECIPE = 'SELECT_RECIPE';
 export const SELECT_RECIPE = 'SELECT_RECIPE';
 
 
+export const DELETE_RECIPE = 'DELETE_RECIPE';
+export const CONFIRM_DELETE_RECIPE = 'CONFIRM_DELETE_RECIPE';
+export const REJECT_DELETE_RECIPE = 'REJECT_DELETE_RECIPE';
+
 export const requestRecipes = (query: string) => ({
 export const requestRecipes = (query: string) => ({
   type: REQUEST_RECIPES,
   type: REQUEST_RECIPES,
   isFetching: true,
   isFetching: true,
@@ -22,6 +28,49 @@ export const selectRecipe = (recipe?: Recipe) => ({
   payload: recipe,
   payload: recipe,
 });
 });
 
 
+export interface DeleteRecipeAction extends Action<'DELETE_RECIPE'> {
+  id: string,
+}
+
+export const pendingDeleteRecipe = (id: string): DeleteRecipeAction => ({
+  type: DELETE_RECIPE,
+  id,
+})
+
+export interface ResultDeleteRecipeAction extends Action<'CONFIRM_DELETE_RECIPE'|'REJECT_DELETE_RECIPE'> {
+  result: any
+}
+
+export const confirmDeleteRecipe = (result: any): ResultDeleteRecipeAction => ({
+  type: CONFIRM_DELETE_RECIPE,
+  result,
+});
+
+export const rejectDeleteRecipe = (result: any): ResultDeleteRecipeAction => ({
+  type: REJECT_DELETE_RECIPE,
+  result,
+})
+
+export const deleteRecipeActionCreator: ActionCreator<
+  ThunkAction<
+    Promise<ResultDeleteRecipeAction>,
+    any,
+    any,
+    ResultDeleteRecipeAction
+  >
+> = (id: string) => {
+  return async (dispatch: Dispatch) => {
+    dispatch(pendingDeleteRecipe(id))
+    try {
+      const result = await deleteRecipe(id);
+      fetchRecipes('')(dispatch)
+      return dispatch(confirmDeleteRecipe(result))
+    } catch (error) {
+      return dispatch(rejectDeleteRecipe(error))
+    }
+  }
+}
+
 export function fetchRecipes(query: string) {
 export function fetchRecipes(query: string) {
   return (dispatch: any) => {
   return (dispatch: any) => {
     dispatch(requestRecipes(query))
     dispatch(requestRecipes(query))

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

@@ -3,6 +3,7 @@ import {
   fetchIfNeeded as fetch,
   fetchIfNeeded as fetch,
   receiveRecipes as receive,
   receiveRecipes as receive,
   selectRecipe as select,
   selectRecipe as select,
+  deleteRecipeActionCreator as deleteRecipe,
 } from "containers/Recipes/List/actions";
 } from "containers/Recipes/List/actions";
 import {
 import {
   addRecipeToCart,
   addRecipeToCart,
@@ -34,7 +35,8 @@ interface RecipeListProps extends RouteComponentProps {
   selectRecipe: (recipe?: DBRecipe) => undefined,
   selectRecipe: (recipe?: DBRecipe) => undefined,
   removeFromCart: (recipe: DBRecipe) => undefined,
   removeFromCart: (recipe: DBRecipe) => undefined,
   addRecipeToCart: (recipe: DBRecipe) => undefined,
   addRecipeToCart: (recipe: DBRecipe) => undefined,
-  addRecipeToPlanner: (recipe: DBRecipe) => undefined
+  addRecipeToPlanner: (recipe: DBRecipe) => undefined,
+  deleteRecipe: (id: string) => undefined
 };
 };
 
 
 class RecipeList extends Component<RecipeListProps, {phoneDisplay: boolean, search: string}> {
 class RecipeList extends Component<RecipeListProps, {phoneDisplay: boolean, search: string}> {
@@ -98,6 +100,11 @@ class RecipeList extends Component<RecipeListProps, {phoneDisplay: boolean, sear
   handleAddToPlanner = (recipe: DBRecipe) => (event: React.MouseEvent) => {
   handleAddToPlanner = (recipe: DBRecipe) => (event: React.MouseEvent) => {
     this.props.addRecipeToPlanner(recipe)
     this.props.addRecipeToPlanner(recipe)
   }
   }
+
+  handleDeleteRecipe = (id: string) => (event: React.MouseEvent) => {
+    this.props.deleteRecipe(id)
+  }
+
   handler = (event: React.MouseEvent) => {
   handler = (event: React.MouseEvent) => {
     console.log('click', event);
     console.log('click', event);
   }
   }
@@ -116,6 +123,9 @@ class RecipeList extends Component<RecipeListProps, {phoneDisplay: boolean, sear
   icons = (id = '') => [{
   icons = (id = '') => [{
     icon: 'open_in_new',
     icon: 'open_in_new',
     handler: () => this.props.history.push('/recipes/view/' + id)
     handler: () => this.props.history.push('/recipes/view/' + id)
+  }, {
+    icon: 'delete_outline',
+    handler: this.handleDeleteRecipe(id)
   }]
   }]
 
 
   render() {
   render() {
@@ -203,6 +213,9 @@ const mapDispatchToProps = (dispatch: any) => {
     },
     },
     addRecipeToPlanner: (recipe: DBRecipe) => {
     addRecipeToPlanner: (recipe: DBRecipe) => {
       dispatch(plannerActions.addToBacklog(recipe))
       dispatch(plannerActions.addToBacklog(recipe))
+    },
+    deleteRecipe: (id: string) => {
+      dispatch(deleteRecipe(id))
     }
     }
   }
   }
 }
 }

+ 23 - 1
recipes/src/containers/Recipes/List/reducers.ts

@@ -2,7 +2,9 @@ const initialState = {
   isFetching: false,
   isFetching: false,
   data: [],
   data: [],
   selectedRecipe: undefined,
   selectedRecipe: undefined,
-  shoppingCart: []
+  shoppingCart: [],
+  id: '',
+  result: undefined
 };
 };
 
 
 export const recipesReducer = (
 export const recipesReducer = (
@@ -26,6 +28,26 @@ export const recipesReducer = (
         ...state,
         ...state,
         selectedRecipe: action.payload
         selectedRecipe: action.payload
       }
       }
+    case 'DELETE_RECIPE':
+      return {
+        ...state,
+        id: action.id,
+        isFetching: true
+      }
+    case 'CONFIRM_DELETE_RECIPE':
+      return {
+        ...state,
+        isFetching: false,
+        id: '',
+        result: action.result
+      }
+    case 'REJECT_DELETE_RECIPE':
+      return {
+        ...state,
+        isFetching: false,
+        id: '',
+        result: action.result
+      }
     default:
     default:
       return state;
       return state;
   }
   }

+ 9 - 1
recipes/src/containers/Recipes/services.ts

@@ -27,10 +27,18 @@ export const updateRecipe = (recipe: DBRecipe): Promise<any> =>
       recipe
       recipe
     ).then(response => response);
     ).then(response => response);
 
 
+export const deleteRecipe = (id: string): Promise<any> =>
+  axios.delete(`${API}/${id}`)
+      .then(response => ({
+        data: response.data,
+        statusText: response.statusText
+      }))
+
 export default {
 export default {
   getRecipes,
   getRecipes,
   getRecipeById,
   getRecipeById,
   scrapeRecipe,
   scrapeRecipe,
   saveRecipe,
   saveRecipe,
-  updateRecipe
+  updateRecipe,
+  deleteRecipe
 }
 }