Skip to content

Commit

Permalink
Address PR feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
jimbo committed Aug 13, 2018
1 parent 4ea0d0a commit 5df5a8b
Show file tree
Hide file tree
Showing 9 changed files with 187 additions and 134 deletions.
69 changes: 36 additions & 33 deletions packages/venia-concept/src/actions/cart.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,19 @@ export const createGuestCart = () =>
return;
}

// reset checkout, then request a new guest cart
// reset the checkout workflow
// in case the user has already completed an order this session
dispatch(checkoutActions.reset());

const guestCartId = await retrieveGuestCartId();

// if a guest cart exists in storage, act like we just received it
if (guestCartId) {
dispatch(actions.receiveGuestCart(guestCartId));
return;
}

// otherwise, request a new guest cart
dispatch(actions.requestGuestCart());

try {
Expand All @@ -54,10 +65,15 @@ export const addItemToCart = (payload = {}) => {

writeImageToCache(item);

return async function thunk(dispatch) {
const guestCartId = await getGuestCartId(...arguments);

return async function thunk(dispatch, getState) {
try {
const { cart } = getState();
const { guestCartId } = cart;

if (!guestCartId) {
throw new Error('Missing required information: guestCartId');
}

const cartItem = await request(
`/rest/V1/guest-carts/${guestCartId}/items`,
{
Expand Down Expand Up @@ -98,10 +114,18 @@ export const addItemToCart = (payload = {}) => {
export const getCartDetails = (payload = {}) => {
const { forceRefresh } = payload;

return async function thunk(dispatch) {
dispatch(actions.requestDetails());
return async function thunk(dispatch, getState) {
const { cart } = getState();
const { guestCartId } = cart;

dispatch(actions.requestDetails(guestCartId));

const guestCartId = await getGuestCartId(...arguments);
// if there isn't a guest cart, create one
// then retry this operation
if (!guestCartId) {
await dispatch(createGuestCart());
return thunk(...arguments);
}

try {
const [imageCache, details, totals] = await Promise.all([
Expand Down Expand Up @@ -160,41 +184,20 @@ export const toggleCart = () =>

async function fetchCartPart({ guestCartId, forceRefresh, subResource = '' }) {
if (!guestCartId) {
return null;
throw new Error('Missing required information: guestCartId');
}

return request(`/rest/V1/guest-carts/${guestCartId}/${subResource}`, {
cache: forceRefresh ? 'reload' : 'default'
});
}

export async function clearGuestCartId() {
return storage.removeItem('guestCartId');
export async function retrieveGuestCartId() {
return storage.getItem('guestCartId');
}

export async function getGuestCartId(dispatch, getState) {
const { cart } = getState();

// ensure state slices are present
if (!cart) {
return null;
}

if (!cart.guestCartId) {
// check for a guest cart in storage
const storedGuestCartId = await storage.getItem('guestCartId');

// if one exists, return it
if (storedGuestCartId) {
return storedGuestCartId;
}

// otherwise create a guest cart
await dispatch(createGuestCart());
}

// retrieve the new guest cart from state
return getState().cart.guestCartId;
export async function clearGuestCartId() {
return storage.removeItem('guestCartId');
}

async function retrieveImageCache() {
Expand Down
44 changes: 23 additions & 21 deletions packages/venia-concept/src/actions/checkout.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { createActions } from 'redux-actions';
import { RestApi } from '@magento/peregrine';

import { closeDrawer } from 'src/actions/app';
import { clearGuestCartId, getGuestCartId } from 'src/actions/cart';
import { clearGuestCartId, getCartDetails } from 'src/actions/cart';

const prefix = 'CHECKOUT';
const actionTypes = ['EDIT', 'RESET'];
Expand Down Expand Up @@ -52,25 +52,27 @@ export const submitCart = () =>
};

export const submitInput = () =>
async function thunk(dispatch) {
dispatch(actions.input.submit());
async function thunk(dispatch, getState) {
const { cart } = getState();
const { guestCartId } = cart;

try {
const guestCartId = await getGuestCartId(...arguments);
if (!guestCartId) {
throw new Error('Missing required information: guestCartId');
}

if (!guestCartId) {
throw new Error('Missing required information: guestCartId');
}
dispatch(actions.input.submit());

try {
const address = formatAddress();
const response = await request(
`/rest/V1/guest-carts/${guestCartId}/shipping-information`,
{
method: 'POST',
// TODO: replace with real data from cart state
body: JSON.stringify({
addressInformation: {
billing_address: getAddress(),
shipping_address: getAddress(),
billing_address: address,
shipping_address: address,
shipping_method_code: 'flatrate',
shipping_carrier_code: 'flatrate'
}
Expand All @@ -79,22 +81,24 @@ export const submitInput = () =>
);

dispatch(actions.input.accept(response));
dispatch(getCartDetails({ forceRefresh: true }));
} catch (error) {
dispatch(actions.input.reject(error));
}
};

export const submitOrder = () =>
async function thunk(dispatch) {
dispatch(actions.order.submit());
async function thunk(dispatch, getState) {
const { cart } = getState();
const { guestCartId } = cart;

try {
const guestCartId = await getGuestCartId(...arguments);
if (!guestCartId) {
throw new Error('Missing required information: guestCartId');
}

if (!guestCartId) {
throw new Error('Missing required information: guestCartId');
}
dispatch(actions.order.submit());

try {
const response = await request(
`/rest/V1/guest-carts/${guestCartId}/order`,
{
Expand All @@ -117,7 +121,6 @@ export const submitOrder = () =>

/* helpers */

// TODO: replace with real address data
const mockAddress = {
country_id: 'US',
firstname: 'Veronica',
Expand All @@ -132,7 +135,6 @@ const mockAddress = {
email: '[email protected]'
};

// TODO: replace with real address data
function getAddress() {
return mockAddress;
function formatAddress(address = mockAddress) {
return address;
}
38 changes: 27 additions & 11 deletions packages/venia-concept/src/components/Checkout/flow.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
import { Component, createElement } from 'react';
import { bool, func, shape, string } from 'prop-types';
import { bool, func, object, shape, string } from 'prop-types';

import classify from 'src/classify';
import Cart from './cart';
import Form from './form';
import Receipt from './receipt';
import defaultClasses from './flow.css';

const stepMap = {
cart: 1,
form: 2,
receipt: 3
};

const isCartReady = items => items > 0;
const isAddressValid = address => !!(address && address.email);

class Flow extends Component {
static propTypes = {
actions: shape({
Expand All @@ -16,37 +25,44 @@ class Flow extends Component {
submitInput: func.isRequired,
submitOrder: func.isRequired
}).isRequired,
cart: shape({
details: object,
guestCartId: string,
totals: object
}),
checkout: shape({
editing: string,
step: string,
submitting: bool,
valid: bool
submitting: bool
}),
classes: shape({
root: string
}),
ready: bool
})
};

get child() {
const { actions, checkout, ready } = this.props;
const { actions, cart, checkout } = this.props;
const {
editOrder,
resetCheckout,
submitCart,
submitInput,
submitOrder
} = actions;
const { editing, step, submitting, valid } = checkout;
const { editing, step, submitting } = checkout;
const { details } = cart;
const ready = isCartReady(details.items_count);
const valid = isAddressValid(details.billing_address);

switch (step) {
case 'cart': {
switch (stepMap[step]) {
case 1: {
const stepProps = { ready, submitCart, submitting };

return <Cart {...stepProps} />;
}
case 'form': {
case 2: {
const stepProps = {
cart,
editOrder,
editing,
submitInput,
Expand All @@ -57,7 +73,7 @@ class Flow extends Component {

return <Form {...stepProps} />;
}
case 'receipt': {
case 3: {
const stepProps = { resetCheckout };

return <Receipt {...stepProps} />;
Expand Down
Loading

0 comments on commit 5df5a8b

Please sign in to comment.