Forráskód Böngészése

Add Sort in shopping cart

Tatiana Inama 6 éve
szülő
commit
d2069e4ccf

+ 38 - 17
recipes/src/containers/ShoppingCart/View/index.tsx

@@ -10,7 +10,7 @@ import List from 'components/List';
 
 import shoppingCartActions, { fetchCartActionCreator, saveCartActionCreator } from 'containers/ShoppingCart/actions';
 
-import { ShoppingItem, ShoppingCartState } from 'types/shopping-cart';
+import { ShoppingItem, ShoppingCartState, SortType } from 'types/shopping-cart';
 import { AppState } from 'store/configureStore';
 
 import { combineMultipleItems } from '../services';
@@ -93,7 +93,7 @@ class ShoppingCartView extends React.Component<ShoppingCartViewProps, ShoppingCa
     const { selected, selectedMeasure } = this.state;
     if (selectedMeasure && selected.every(item => selectedMeasure.values.includes(item.unit))) {
       try {
-        this.props.mergeItemsCart(this.state.selected.map(selected => selected._original), combineMultipleItems(this.state.selected));
+        this.props.mergeItemsCart(this.state.selected, combineMultipleItems(this.state.selected));
         this.clearSelection();
       } catch(error) {
         console.log(error)
@@ -115,6 +115,15 @@ class ShoppingCartView extends React.Component<ShoppingCartViewProps, ShoppingCa
     this.clearSelection();
   }
 
+  sortItems = (event: React.ChangeEvent<HTMLSelectElement>) => {
+    try {
+      const sort: SortType = parseInt(event.target.value);
+      this.props.sortCart(sort);
+    } catch (error) {
+      console.log('error while trying to sort items', error)
+    }
+  }
+
   render () {
     return (
       <section className='cbk-shopping-cart-view'>
@@ -122,21 +131,33 @@ class ShoppingCartView extends React.Component<ShoppingCartViewProps, ShoppingCa
             this.props.items.length ? (
               <>
                 <div className='cbk-shopping-cart-view__actions'>
-                  {
-                    this.state.selected.length >= 2 ? (
-                      <div className='cbk-shopping-cart-view__actions--selection-actions'>
-                        <Button outlined onClick={this.mergeItems}>
-                          Merge
-                        </Button>
-                        <Button outlined onClick={this.removeItems}>
-                          Remove
-                        </Button>
-                        <Button outlined onClick={this.clearSelection}>
-                          Clear
-                        </Button>
-                      </div>
-                    ) : null
-                  }
+                  <div className='cbk-shopping-cart-view__actions--selection-actions'>
+                    {
+                      this.state.selected.length ? (
+                        <>
+                          <Button outlined onClick={this.removeItems}>
+                            Remove
+                          </Button>
+                          <Button outlined onClick={this.clearSelection}>
+                            Clear
+                          </Button>
+                          {
+                            this.state.selected.length > 1 && (
+                              <Button outlined onClick={this.mergeItems}>
+                                Merge
+                              </Button>
+                            )
+                          }
+                        </>
+                      ) : null
+                    }
+                  </div>
+                  <select onChange={this.sortItems} defaultValue=''>
+                    <option value='' disabled>Sort by</option>
+                    <option value={SortType.Ingredient}>Ingredients</option>
+                    <option value={SortType.Recipe}>Recipe</option>
+                    {/* <option value={SortType.Planner}>Planner</option> */}
+                  </select>
                   <Button outlined onClick={() => this.openDialog(true) }>
                     Delete
                   </Button>

+ 13 - 5
recipes/src/containers/ShoppingCart/actions.ts

@@ -1,6 +1,5 @@
 import { ThunkAction } from 'redux-thunk';
-import { DBRecipe, SubRecipe } from 'types/recipes';
-import { ShoppingRecipe, DBShoppingCart, ShoppingItem } from 'types/shopping-cart';
+import { ShoppingRecipe, DBShoppingCart, ShoppingItem, SortType } from 'types/shopping-cart';
 import { bindActionCreators, Action, ActionCreator, Dispatch } from 'redux';
 import { fetchShoppingCart, saveShoppingCart } from './services';
 
@@ -21,6 +20,7 @@ export const REJECT_SAVE_CART = 'REJECT_SAVE_CART';
 export const DELETE_CART = 'DELETE_CART';
 
 export const MERGE_ITEMS_CART = 'MERGE_ITEMS_CART';
+export const SORT_CART = 'SORT_CART';
 
 export const addRecipeToCart = (recipe: ShoppingRecipe): AddRecipeToCart => ({
   type: ADD_RECIPE_TO_CART,
@@ -111,7 +111,7 @@ export const deleteCart = (): DeleteCartAction => ({
   type: DELETE_CART
 })
 
-export const mergeItemsCart = (deletedItems: string[], newItem: ShoppingItem): MergeItemsCartAction => ({
+export const mergeItemsCart = (deletedItems: ShoppingItem[], newItem: ShoppingItem): MergeItemsCartAction => ({
   type: MERGE_ITEMS_CART,
   payload: {
     items: deletedItems,
@@ -124,6 +124,11 @@ export const removeMultipleItemsFromCart = (items: ShoppingItem[]): RemoveMultip
   payload: items
 })
 
+export const sortCart = (sort: SortType): SortCartAction => ({
+  type: SORT_CART,
+  payload: sort
+})
+
 export type AddRecipeToCart = {
   type: typeof ADD_RECIPE_TO_CART,
   payload: ShoppingRecipe
@@ -154,8 +159,9 @@ export interface PendingSaveCartAction extends Action<'PENDING_SAVE_CART'> { car
 export interface ConfirmSaveCartAction extends Action<'CONFIRM_SAVE_CART'> { cart: DBShoppingCart };
 export interface RejectSaveCartAction extends Action<'REJECT_SAVE_CART'> { error: string };
 export interface DeleteCartAction extends Action<'DELETE_CART'> {};
-export interface MergeItemsCartAction extends Action<'MERGE_ITEMS_CART'> { payload: { items: string[], newItem: ShoppingItem }};
+export interface MergeItemsCartAction extends Action<'MERGE_ITEMS_CART'> { payload: { items: ShoppingItem[], newItem: ShoppingItem }};
 export interface RemoveMultipleItemsFromCartAction extends Action<'REMOVE_MULTIPLE_ITEMS_FROM_CART'> { payload: ShoppingItem[] };
+export interface SortCartAction extends Action<'SORT_CART'> { payload: SortType };
 
 export type ActionTypes = 
   AddRecipeToCart | 
@@ -171,7 +177,8 @@ export type ActionTypes =
   RejectSaveCartAction |
   DeleteCartAction |
   MergeItemsCartAction |
-  RemoveMultipleItemsFromCartAction;
+  RemoveMultipleItemsFromCartAction |
+  SortCartAction;
 
 export default {
   addRecipeToCart,
@@ -182,4 +189,5 @@ export default {
   deleteCart,
   mergeItemsCart,
   removeMultipleItemsFromCart,
+  sortCart
 }

+ 22 - 5
recipes/src/containers/ShoppingCart/reducers.ts

@@ -1,5 +1,5 @@
 
-import ShoppingItem, { ShoppingCartState } from 'types/shopping-cart';
+import ShoppingItem, { ShoppingCartState, SortType } from 'types/shopping-cart';
 import { ActionTypes,
   ADD_RECIPE_TO_CART,
   REMOVE_RECIPE_FROM_CART,
@@ -13,10 +13,11 @@ import { ActionTypes,
   REQUEST_CART,
   RECEIVE_CART,
   MERGE_ITEMS_CART,
-  REMOVE_MULTIPLE_ITEMS_FROM_CART
+  REMOVE_MULTIPLE_ITEMS_FROM_CART,
+  SORT_CART
 } from './actions';
 import { createShoppingList, getItemsFromRecipe } from './services';
-import { insert, without } from 'ramda';
+import { insert, without, sort, ascend, prop, equals } from 'ramda';
 
 const initialState: ShoppingCartState = {
     items: [],
@@ -24,6 +25,17 @@ const initialState: ShoppingCartState = {
     isFetching: false,
 };
 
+const sortSelection = (sort: SortType) => {
+  switch(sort) {
+    case SortType.Ingredient:
+      return ascend(prop('name'))
+    case SortType.Recipe:
+      return ascend(prop('recipeName'))
+    default:
+      return ascend(prop('name'))
+  }
+}
+
 const shoppingCartReducer = (
   state = initialState,
   action: ActionTypes
@@ -96,16 +108,21 @@ const shoppingCartReducer = (
         items: action.payload.items
       }
     case MERGE_ITEMS_CART:
-      const index = state.items.findIndex(i => i._original === action.payload.items[0]);
+      const index = state.items.findIndex(equals(action.payload.items[0]));
       return {
         ...state,
-        items: insert(index, action.payload.newItem, state.items.filter((item) => !action.payload.items.includes(item._original)))
+        items: insert(index, action.payload.newItem, without(action.payload.items, state.items))
       }
     case REMOVE_MULTIPLE_ITEMS_FROM_CART:
       return {
         ...state,
         items: without(action.payload, state.items)
       }
+    case SORT_CART: 
+      return {
+        ...state,
+        items: sort(sortSelection(action.payload), state.items)
+      }
     default:
       return state
   }

+ 7 - 1
recipes/src/types/shopping-cart.ts

@@ -2,7 +2,7 @@ import Recipe, { Ingredient, SubRecipe } from './recipes';
 
 export interface ShoppingItem extends Ingredient {
   recipeId?: string,
-  recipeName?: string[]
+  recipeName: string[]
 }
 
 export interface ShoppingRecipe {
@@ -24,4 +24,10 @@ export type ShoppingCartState = {
   error?: string,
 }
 
+export enum SortType {
+  Ingredient,
+  Recipe,
+  Planner
+}
+
 export default ShoppingItem;