Skip to content

Commit

Permalink
#10: Implement the third page, Select Menu Items
Browse files Browse the repository at this point in the history
 - Cart ('Your tray') has its own actions column with ability to add/remove items and update subtotal
  • Loading branch information
dartandrevinsky committed May 24, 2021
1 parent 7a259ad commit 2351850
Show file tree
Hide file tree
Showing 11 changed files with 296 additions and 256 deletions.
32 changes: 18 additions & 14 deletions server/src/api/cart.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import resource from 'resource-router-middleware';

const initialCart = {
name: 'new cart'
};
const initialCart = {};

const inMemoCart = {
current: null
Expand All @@ -16,20 +14,18 @@ const cartResource = ({ config, db }) => resource({

/** POST / - Create a new entity */
create(req, res) {
if (!inMemoCart.current) {
inMemoCart.current = Object.assign({}, initialCart, {
id: String(new Date().getTime()),
items: []
});
}
inMemoCart.current = Object.assign({}, initialCart, {
id: String(new Date().getTime()),
items: []
});

res.json(inMemoCart.current);
},

/** PUT /:id - Update a given entity */
update({ body, ...req }, res) {

const id = req.params[facetName];
const id = req.params[ facetName ];
console.log(id, body);
debugger;

Expand All @@ -45,14 +41,22 @@ const cartResource = ({ config, db }) => resource({
...inMemoCart.current.items,
result
];
res.send(result);
console.log(JSON.stringify(inMemoCart.current.items, null, 2));
return new Promise(rs => setTimeout(() => {
res.send(result);
rs();
}, 2000));
} else {
const result = Object.assign(inMemoCart.current.items[idx], {
const result = Object.assign(inMemoCart.current.items[ idx ], {
count: body.qty
});
res.send(result);
// res.send(result);
console.log(JSON.stringify(inMemoCart.current.items, null, 2));
return new Promise(rs => setTimeout(() => {
res.send(result);
rs();
}, 2000));
}
return;
}

res.sendStatus(404);
Expand Down
1 change: 1 addition & 0 deletions src/app/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ const connectedReducer = makeConnectedReducer(history);

export const store = configureStore({
reducer: connectedReducer,
devTools: true,
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(routerMiddleware(history))
});
26 changes: 10 additions & 16 deletions src/features/cart/cartSlice.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ export const updateCartWithItemAsyncThunk = createAsyncThunk(
const initialState = {
id: null,
status: null,
items: [],
hash: ''
items: []
};

export const accessCart = (propName) => ({ [ ns ]: state }) => propName ? (state?.[ propName ]) : state;
Expand All @@ -51,15 +50,13 @@ export const cartSlice = createSlice({
state.items = [];
})
.addCase(updateCartWithItemAsyncThunk.pending, (state, { payload, meta }) => {
console.log(payload, meta);
debugger;
const { itemId, item, restaurantId, qty } = meta.arg;
const idx = state.items.findIndex(i => i.id === itemId);
if (idx >= 0) {
state.items = [
...state.items.slice(0, idx),
Object.assign({}, state.items[ idx ], {
count: state.items[ idx ].count + qty,
count: qty,
oldCount: state.items[ idx ].count
}),
...state.items.slice(idx + 1)
Expand All @@ -68,37 +65,35 @@ export const cartSlice = createSlice({
state.items = [
...state.items,
Object.assign({}, item, {
id: itemId,
meta: { restaurantId },
count: qty,
oldCount: 0
})
];
}
state.hash = calculateHash(state.items);

})
.addCase(updateCartWithItemAsyncThunk.fulfilled, (state, { payload, meta }) => {
console.log(payload, meta);
debugger;
const { itemId } = meta.arg;
const idx = state.items.findIndex(item => item.id === itemId);
if (idx < 0) {
return;
}

const oldItem = state.items[ idx ];
debugger;

state.items = [
...state.items.slice(0, idx),
Object.assign({}, state.items[ idx ], {
...(oldItem.count ? [ Object.assign({}, state.items[ idx ], {
oldCount: undefined
}),
}) ] : []),
...state.items.slice(idx + 1)
];
state.hash = calculateHash(state.items);

})
.addCase(updateCartWithItemAsyncThunk.rejected, (state, { payload, meta, error }) => {
console.log(payload, meta);
debugger;
const { itemId } = meta.arg;
const idx = state.items.findIndex(item => item.id === itemId);
if (idx < 0) {
Expand All @@ -115,9 +110,6 @@ export const cartSlice = createSlice({
]),
...state.items.slice(idx + 1)
];
state.hash = calculateHash(state.items);



})
});
Expand All @@ -126,6 +118,8 @@ function calculateHash(arr) {
return arr.map(i => [ i.id, i.count, i.oldCount ?? '' ].join('|')).join(';');
}

void calculateHash;

export const { resetCart } = cartSlice.actions;

const namedReducer = {
Expand Down
4 changes: 2 additions & 2 deletions src/features/restaurants/restaurantsSlice.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ export const { resetSelectedRestaurant, keepSelectedRestaurant } = restaurantsSl

export const accessSelectedRestaurantId = () => ({ [ ns ]: state }) => state.selectedRestaurantId;
export const accessRestaurantMenuState = (restaurantId) => ({ [ ns ]: state }) => state.menuState[ restaurantId ];
export const accessMenuForRestaurant = (restaurantId) => ({ [ ns ]: state }) => state.menus[ restaurantId ] ?
export const accessMenuForRestaurant = (restaurantId, fallback) => ({ [ ns ]: state }) => (state.menus[ restaurantId ] ?
selectAll(state.menus[ restaurantId ]) :
undefined;
undefined) || fallback;

const namedReducer = {
[ ns ]: restaurantsSlice.reducer
Expand Down
3 changes: 0 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,3 @@ ReactDOM.render(rootAppNode,
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
export { LessLargeTextDiv } from './ui/elements/textElements';
export { LargeTextDiv } from './ui/elements/textElements';
export { SelectedRestaurantRow } from './ui/components/SelectedRestaurantRow';
2 changes: 2 additions & 0 deletions src/ui/elements/icons.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { FaSync as FaRefresh } from 'react-icons/fa';
import { FaHamburger, FaMapMarkerAlt, FaClock, FaSearch, FaEdit, FaPlus, FaMinus, FaCartPlus } from 'react-icons/fa';
import { FaChevronRight } from 'react-icons/fa'
import React from 'react';
import theme from './icons.module.scss'

Expand All @@ -12,3 +13,4 @@ export const IconEdit = FaEdit;
export const IconPlus = FaPlus;
export const IconCartPlus = FaCartPlus;
export const IconMinus = FaMinus;
export const IconChevronRight = FaChevronRight;
4 changes: 2 additions & 2 deletions src/ui/elements/paginatedTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ export const PaginatedTable = ({
/></div>
<div className={ paginationOnTop ? 'order-0' : 'order-1' }>
<div className="d-flex flex-row justify-content-between align-content-start flex-wrap">
<SizePerPageDropdownStandalone
<div className="d-inline-block mb-3"><SizePerPageDropdownStandalone
{ ...paginationProps }
/>
/></div>

<PaginationListStandalone
{ ...paginationProps }
Expand Down
37 changes: 37 additions & 0 deletions src/ui/pages/RestaurantPage/hooks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { debugged } from '../../../shared/diagnostics';
import { useDispatch } from 'react-redux';
import { useMemo } from 'react';
import curry from 'lodash-es/curry';
import { updateCartWithItemAsyncThunk } from '../../../features/cart/cartSlice';

/**
*
* @param cartId
* @param cartItemsMap
* @param selectedRestaurantId
* @return {*|(function(*, *): function(*): (function(...[*]): (*|undefined))|*)}
*/
export function useUpdateCartHandler(cartId, cartItemsMap, selectedRestaurantId) {
const dummyHandler = (a, b) => (c) => debugged([ a, b, c ]);

const dispatch = useDispatch();
return useMemo(() => cartId ? curry((itemId, menuItem, cartItem, diff, _) => {
const item = cartItem || { count: 0, name: menuItem?.name, price: menuItem?.price };
const restaurantId = selectedRestaurantId ?? (item.meta?.restaurantId ?? null);
if (typeof item.oldCount !== 'undefined') {
return;
}
dispatch(updateCartWithItemAsyncThunk({
cartId,
restaurantId,
itemId,
qty: Math.max(0, item.count + diff),
item
}));
debugger;
}) : dummyHandler, [ cartId, selectedRestaurantId, dispatch ]);
}

export function createMap(arr, idGetter) {
return new Map(arr.map(i => [ idGetter(i), i ]));
}
Loading

0 comments on commit 2351850

Please sign in to comment.