From bee77a70c49bb22e1dee2a52c5877cc3fb785cfb Mon Sep 17 00:00:00 2001 From: George Schneeloch Date: Tue, 14 May 2019 14:35:58 -0400 Subject: [PATCH] Use query parameters when loading checkout page --- static/js/containers/pages/CheckoutPage.js | 46 ++++++++++++++----- .../js/containers/pages/CheckoutPage_test.js | 9 ++-- static/js/lib/ecommerce.js | 19 ++++++++ 3 files changed, 57 insertions(+), 17 deletions(-) diff --git a/static/js/containers/pages/CheckoutPage.js b/static/js/containers/pages/CheckoutPage.js index cbd3aceaf2..dc274876c9 100644 --- a/static/js/containers/pages/CheckoutPage.js +++ b/static/js/containers/pages/CheckoutPage.js @@ -2,15 +2,17 @@ import React from "react" import * as R from "ramda" import { connect } from "react-redux" -import { connectRequest, mutateAsync } from "redux-query" +import { mutateAsync, requestAsync } from "redux-query" import { compose } from "redux" +import queryString from "query-string" import queries from "../../lib/queries" import { calculateDiscount, calculatePrice, formatPrice, - formatRunTitle + formatRunTitle, + formatErrors } from "../../lib/ecommerce" import { createCyberSourceForm } from "../../lib/form" @@ -64,6 +66,26 @@ export class CheckoutPage extends React.Component { errors: null } + componentDidMount = async () => { + const { + fetchBasket, + location: { search } + } = this.props + const params = queryString.parse(search) + const productId = parseInt(params.product) + if (!productId) { + await fetchBasket() + return + } + + await this.updateBasket({ items: [{ id: productId }] }) + + const couponCode = params.code + if (couponCode) { + await this.updateBasket({ coupons: [{ code: couponCode }] }) + } + } + handleErrors = async (responsePromise: Promise<*>) => { const response = await responsePromise if (response.body.errors) { @@ -202,13 +224,14 @@ export class CheckoutPage extends React.Component { const { basket } = this.props const { couponCode, errors } = this.state - if (!basket) { - return null - } - - const item = basket.items[0] + const item = basket && basket.items[0] if (!item) { - return
No item in basket
+ return ( +
+ No item in basket + {formatErrors(errors)} +
+ ) } const coupon = basket.coupons.find(coupon => @@ -259,7 +282,7 @@ export class CheckoutPage extends React.Component { Apply - {errors ?
Error: {errors}
: null} + {formatErrors(errors)} @@ -302,15 +325,14 @@ const mapStateToProps = state => ({ }) const mapDispatchToProps = dispatch => ({ checkout: () => dispatch(mutateAsync(queries.ecommerce.checkoutMutation())), + fetchBasket: () => dispatch(requestAsync(queries.ecommerce.basketQuery())), updateBasket: payload => dispatch(mutateAsync(queries.ecommerce.basketMutation(payload))) }) -const mapPropsToConfigs = () => [queries.ecommerce.basketQuery()] export default compose( connect( mapStateToProps, mapDispatchToProps - ), - connectRequest(mapPropsToConfigs) + ) )(CheckoutPage) diff --git a/static/js/containers/pages/CheckoutPage_test.js b/static/js/containers/pages/CheckoutPage_test.js index 16c7549de3..299b5fd3e9 100644 --- a/static/js/containers/pages/CheckoutPage_test.js +++ b/static/js/containers/pages/CheckoutPage_test.js @@ -36,7 +36,9 @@ describe("CheckoutPage", () => { basket } }, - {} + { + location: {} + } ) }) @@ -167,10 +169,7 @@ describe("CheckoutPage", () => { }) assert.equal(inner.state().errors, errors) - assert.equal( - inner.find(".enrollment-input .error").text(), - "Error: Unknown error" - ) + assert.equal(inner.find(".enrollment-input .error").text(), "Unknown error") assert.isTrue(inner.find(".enrollment-input input.error-border").exists()) }) diff --git a/static/js/lib/ecommerce.js b/static/js/lib/ecommerce.js index 87c6271471..3e330f91ef 100644 --- a/static/js/lib/ecommerce.js +++ b/static/js/lib/ecommerce.js @@ -1,4 +1,5 @@ // @flow +import React from "react" import Decimal from "decimal.js-light" import * as R from "ramda" import { equals } from "ramda" @@ -57,6 +58,24 @@ const formatDateForRun = (dateString: ?string) => export const formatRunTitle = (run: CourseRun) => `${formatDateForRun(run.start_date)} - ${formatDateForRun(run.end_date)}` +export const formatErrors = (errors: string | Object) => { + if (!errors) { + return null + } + + let errorString + if (typeof errors === "object") { + if (errors.items) { + errorString = errors.items[0] + } else { + errorString = errors[0] + } + } else { + errorString = errors + } + return
{errorString}
+} + export const isPromo = equals(COUPON_TYPE_PROMO) export const createProductMap = (