Skip to content

Commit

Permalink
add buy now functionality (#656)
Browse files Browse the repository at this point in the history
  • Loading branch information
levenecav authored Oct 19, 2018
1 parent 5e18f60 commit f9b0332
Show file tree
Hide file tree
Showing 8 changed files with 249 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/components/common/Button/Button.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
@import "../../../styles/variables.scss";

.container {
position: relative;
font-family: $font_medium;
height: 4rem;
display: inline-flex;
Expand Down Expand Up @@ -114,7 +115,6 @@
}

.wireframe {
position: relative;
background: transparent;
font-family: $font_regular;
border: $color_blue 1px solid;
Expand Down
4 changes: 4 additions & 0 deletions src/pages/Profile/items/Order/Invoice.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ type PropsType = {
};

class Invoice extends PureComponent<PropsType> {
componentDidMount() {
window.scroll({ top: 0 });
}

render() {
// $FlowIgnoreMe
const invoiceId = pathOr(null, ['order', 'invoice', 'id'], this.props.me);
Expand Down
136 changes: 132 additions & 4 deletions src/pages/Store/Product/Product.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,32 @@ import { createFragmentContainer, graphql } from 'react-relay';
import { routerShape } from 'found';
import PropTypes from 'prop-types';
import xss from 'xss';
import { isNil, head, ifElse, assoc, dissoc, propEq, has, prop } from 'ramda';
import {
isNil,
head,
ifElse,
assoc,
dissoc,
propEq,
has,
prop,
find,
pathOr,
} from 'ramda';
import { Environment } from 'relay-runtime';
import smoothscroll from 'libs/smoothscroll';

import { withErrorBoundary } from 'components/common/ErrorBoundaries';
import { AppContext, Page } from 'components/App';
import { SocialShare } from 'components/SocialShare';
import { Col, Row } from 'layout';
import { IncrementInCartMutation } from 'relay/mutations';
import { IncrementInCartMutation, BuyNowMutation } from 'relay/mutations';
import { withShowAlert } from 'components/App/AlertContext';
import { extractText, isEmpty, log } from 'utils';

import type { AddressFullType } from 'types';
import type { AddAlertInputType } from 'components/App/AlertContext';
import type { MutationParamsType } from 'relay/mutations/BuyNowMutation';

import {
makeWidgets,
Expand Down Expand Up @@ -49,9 +63,24 @@ import type {
import './Product.scss';

type PropsType = {
me: {
id: string,
rawId: number,
phone: ?string,
firstName: string,
lastName: string,
deliveryAddressesFull: ?Array<{
id: string,
address: AddressFullType,
isPriority: boolean,
}>,
},
showAlert: (input: AddAlertInputType) => void,
baseProduct: ProductType,
router: routerShape,
relay: {
environment: Environment,
},
};

type StateType = {
Expand All @@ -65,6 +94,7 @@ type StateType = {
[string]: Array<string>,
},
isAddToCart: boolean,
isLoading: boolean,
};

class Product extends Component<PropsType, StateType> {
Expand Down Expand Up @@ -113,14 +143,15 @@ class Product extends Component<PropsType, StateType> {
selectedAttributes: {},
availableAttributes: {},
isAddToCart: false,
isLoading: false,
};
}

componentDidMount() {
window.scrollTo(0, 0);
}

handleAddToCart = (id: number) => {
handleAddToCart = (id: number, isBuyNow?: boolean) => {
this.setState({ unselectedAttr: null });
const { widgets, selectedAttributes } = this.state;
const unselectedAttr = isNoSelected(
Expand All @@ -146,7 +177,12 @@ class Product extends Component<PropsType, StateType> {
text: 'Product added to cart!',
link: { text: '' },
});
this.setState({ isAddToCart: true });
this.setState({ isAddToCart: true }, () => {
if (isBuyNow) {
this.setState({ isLoading: false });
this.props.router.push('/checkout');
}
});
}
},
onError: error => {
Expand All @@ -165,6 +201,93 @@ class Product extends Component<PropsType, StateType> {
}
};

handleBuyNow = (productId: number) => {
this.setState({ unselectedAttr: null });
const { widgets, selectedAttributes } = this.state;
const unselectedAttr = isNoSelected(
sortByProp('id')(widgets),
selectedAttributes,
);

if (isEmpty(widgets) || !unselectedAttr) {
const { me } = this.props;
const deliveryAddressesFull = me.deliveryAddressesFull || [];
const receiverName = `${me.firstName} ${me.lastName}`;
const receiverPhone = me.phone;
this.setState({ isLoading: true });
if (isEmpty(deliveryAddressesFull) || !receiverName || !receiverPhone) {
this.handleAddToCart(productId, true);
return;
}
const deliveryAddressFull =
find(propEq('isPriority', true))(deliveryAddressesFull) ||
deliveryAddressesFull[0];
const addressFull = deliveryAddressFull.address;

const params: MutationParamsType = {
input: {
clientMutationId: '',
productId,
quantity: 1,
addressFull,
receiverName,
receiverPhone,
currency: 'STQ',
},
environment: this.props.relay.environment,
onCompleted: (response, errors) => {
this.setState({ isLoading: false });
log.debug('Success for BuyNowMutation');
if (response && response.buyNow) {
log.debug('Response: ', response);
this.props.showAlert({
type: 'success',
text: 'Orders successfully created',
link: { text: 'Close.' },
});
const responseOrders = pathOr(
null,
['invoice', 'orders'],
response.buyNow,
);
const order = responseOrders[0];
this.props.router.push(
`/profile/orders/${order.slug}/payment-info`,
);
} else if (!errors) {
this.props.showAlert({
type: 'danger',
text: 'Error :(',
link: { text: 'Close.' },
});
// this.setState({ checkoutInProcess: false });
} else {
log.debug('Errors: ', errors);
this.props.showAlert({
type: 'danger',
text: 'Error :(',
link: { text: 'Close.' },
});
}
},
onError: error => {
this.setState({ isLoading: false });
log.error('Error in BuyNowMutation');
log.error(error);
this.props.showAlert({
type: 'danger',
text: 'Something went wrong :(',
link: { text: 'Close.' },
});
},
};
BuyNowMutation.commit(params);
} else {
this.setState({ unselectedAttr });
smoothscroll.scrollTo(head(unselectedAttr));
}
};

handleWidget = (item: {
attributeId: string,
attributeValue: string,
Expand Down Expand Up @@ -278,6 +401,7 @@ class Product extends Component<PropsType, StateType> {
selectedAttributes,
availableAttributes,
isAddToCart,
isLoading,
} = this.state;
const description = extractText(shortDescription, 'EN', 'No Description');
return (
Expand Down Expand Up @@ -323,12 +447,16 @@ class Product extends Component<PropsType, StateType> {
onAddToCart={() =>
this.handleAddToCart(productVariant.rawId)
}
onBuyNow={() =>
this.handleBuyNow(productVariant.rawId)
}
unselectedAttr={unselectedAttr}
quantity={productVariant.quantity}
preOrder={productVariant.preOrder}
preOrderDays={productVariant.preOrderDays}
isAddToCart={isAddToCart}
router={router}
isLoading={isLoading}
/>
<div styleName="line" />
<ProductStore />
Expand Down
6 changes: 5 additions & 1 deletion src/pages/Store/Product/ProductButtons.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ import './ProductButtons.scss';

type PropsType = {
onAddToCart: () => void,
onBuyNow: () => void,
unselectedAttr: ?Array<string>,
quantity: number,
preOrder: boolean,
isAddToCart: boolean,
router: routerShape,
isLoading: boolean,
};

const ProductButtons = ({
Expand All @@ -23,10 +25,12 @@ const ProductButtons = ({
preOrder,
isAddToCart,
router,
onBuyNow,
isLoading,
}: PropsType) => (
<div styleName="container">
<div styleName="buttons">
<Button disabled big>
<Button big isLoading={isLoading} onClick={onBuyNow}>
Buy now
</Button>
<Button
Expand Down
79 changes: 79 additions & 0 deletions src/relay/mutations/BuyNowMutation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// @flow

import { graphql, commitMutation } from 'react-relay';
import { Environment } from 'relay-runtime';

import type { BuyNowMutationResponse } from './__generated__/BuyNowMutation.graphql';

export type { BuyNowMutationResponse as BuyNowMutationResponseType };

const mutation = graphql`
mutation BuyNowMutation($input: BuyNowInput!) {
buyNow(input: $input) {
cart {
id
totalCount
stores {
edges {
node {
id
}
}
}
}
invoice {
id
amount
priceReservedDueDateTime
state
wallet
transactions {
id
amount
}
orders {
slug
}
}
}
}
`;

type AddressParamsType = {
country: ?string,
value: ?string,
administrativeAreaLevel1: ?string,
administrativeAreaLevel2: ?string,
locality: ?string,
political: ?string,
postalCode: ?string,
route: ?string,
streetNumber: ?string,
};

type BuyNowMutationVariables = {
input: {
receiverName: string,
receiverPhone: string,
addressFull: AddressParamsType,
},
};

export type MutationParamsType = {
...BuyNowMutationVariables,
environment: Environment,
onCompleted: ?(response: ?Object, errors: ?Array<Error>) => void,
onError: ?(error: Error) => void,
};

const commit = (params: MutationParamsType) =>
commitMutation(params.environment, {
mutation,
variables: {
input: params.input,
},
onCompleted: params.onCompleted,
onError: params.onError,
});

export default { commit };
3 changes: 3 additions & 0 deletions src/relay/mutations/CreateOrdersMutation.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ const mutation = graphql`
id
amount
}
orders {
slug
}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/relay/mutations/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,4 @@ export {
default as ResendEmailVerificationLinkMutation,
} from './ResendEmailVerificationLinkMutation';
export { default as UpsertShippingMutation } from './UpsertShippingMutation';
export { default as BuyNowMutation } from './BuyNowMutation';
24 changes: 24 additions & 0 deletions src/routes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,30 @@ const routes = (
Component={ProductCard}
query={graphql`
query routes_ProductCard_Query($productID: Int!) {
me {
id
rawId
phone
firstName
lastName
deliveryAddressesFull {
id
address {
country
countryCode
value
administrativeAreaLevel1
administrativeAreaLevel2
locality
political
postalCode
route
streetNumber
placeId
}
isPriority
}
}
baseProduct(id: $productID) {
...Product_baseProduct
}
Expand Down

0 comments on commit f9b0332

Please sign in to comment.