Skip to content

Commit

Permalink
[Cart v2] ProductListing Component (#2094)
Browse files Browse the repository at this point in the history
* Create basic stub of new product list layout

* Get configurable mocked data working before hooking up network calls

* Hook everything up with data fetches

* - Add remove item logic
- Leverage fragments to auto update the cache

* Give item removal a mask while in flight

* ProductListing tests

* Finish up unit tests for Product

* - Handle item remove error state
- Replace fragment usage in mutation to refetchQueries
- Make a sub-component of CartPage
- Fixup tests

* Fixup some component interactions after mainline merge

* Re-add fetch policies as TODO items to be removed later

* - Validate cart id before fetching data
- Update tests

* - Make detail content flow better based on UX feedback
- Update test snapshots with new element

* Adjust product details line-height

Co-authored-by: Jimmy Sanford <[email protected]>
Co-authored-by: Devagouda <[email protected]>
  • Loading branch information
3 people committed Jan 21, 2020
1 parent bfa6af7 commit cacde9c
Show file tree
Hide file tree
Showing 15 changed files with 1,209 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ export const usePriceSummary = props => {
const [fetchPriceSummary, { error, loading, data }] = useLazyQuery(
props.query,
{
fetchPolicy: 'no-cache'
// TODO: Purposely overfetch and hit the network until all components
// are correctly updating the cache. Will be fixed by PWA-321.
fetchPolicy: 'cache-and-network'
}
);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { useCallback, useState } from 'react';
import { useMutation } from '@apollo/react-hooks';

import { useCartContext } from '../../../context/cart';

export const useProduct = props => {
const {
item,
refetchCartQuery,
refetchPriceQuery,
removeItemMutation
} = props;

const flatProduct = flattenProduct(item);
const [removeItem] = useMutation(removeItemMutation);

const [{ cartId }] = useCartContext();

const [isRemoving, setIsRemoving] = useState(false);
const [isFavorite, setIsFavorite] = useState(false);

const handleToggleFavorites = useCallback(() => {
setIsFavorite(!isFavorite);
}, [isFavorite]);

const handleEditItem = useCallback(() => {
// Edit Item action to be completed by PWA-272.
}, []);

const handleRemoveFromCart = useCallback(async () => {
setIsRemoving(true);
const { error } = await removeItem({
variables: {
cartId,
itemId: item.id
},
refetchQueries: [
{
query: refetchCartQuery,
variables: { cartId }
},
{
query: refetchPriceQuery,
variables: { cartId }
}
]
});

if (error) {
setIsRemoving(false);
console.error('Cart Item Removal Error', error);
}
}, [cartId, item.id, refetchCartQuery, refetchPriceQuery, removeItem]);

return {
handleEditItem,
handleRemoveFromCart,
handleToggleFavorites,
isFavorite,
isRemoving,
product: flatProduct
};
};

const flattenProduct = item => {
const {
configurable_options: options = [],
prices,
product,
quantity
} = item;

const { price } = prices;
const { value: unitPrice, currency } = price;

const { name, small_image } = product;
const { url: image } = small_image;

return { currency, image, name, options, quantity, unitPrice };
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { useLazyQuery } from '@apollo/react-hooks';

import { useCartContext } from '../../../context/cart';
import { useEffect } from 'react';

export const useProductListing = props => {
const { query } = props;

const [{ cartId }] = useCartContext();

const [
fetchProductListing,
{ called, data, error, loading }
] = useLazyQuery(query, {
// TODO: Purposely overfetch and hit the network until all components
// are correctly updating the cache. Will be fixed by PWA-321.
fetchPolicy: 'cache-and-network'
});

useEffect(() => {
if (cartId) {
fetchProductListing({
variables: {
cartId
}
});
}
}, [cartId, fetchProductListing]);

useEffect(() => {
if (error) {
console.error(error);
}
}, [error]);

let items = [];
if (called && !error && !loading) {
items = data.cart.items;
}

return {
isLoading: !!loading,
items
};
};
Loading

0 comments on commit cacde9c

Please sign in to comment.