Skip to content

Commit

Permalink
finished cart/checkout
Browse files Browse the repository at this point in the history
  • Loading branch information
slugb0t committed Aug 8, 2021
1 parent d6e01b0 commit 29ddd25
Show file tree
Hide file tree
Showing 12 changed files with 22,063 additions and 134 deletions.
21,527 changes: 21,507 additions & 20 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,8 @@
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"sass": "^1.37.5"
}
}
179 changes: 120 additions & 59 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,151 +1,189 @@
import React, { Component } from 'react';
import { commerce } from './lib/commerce';
import { FontAwesomeIcon } from '@fortawesome/fontawesome-free';
import { Switch, Route } from 'react-router-dom'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faShoppingBag, faTimes } from '@fortawesome/free-solid-svg-icons'
import { Switch, Route } from 'react-router-dom';
import PropTypes from 'prop-types';
import './styles/styles.scss';

import Cart from './components/Cart';
import Hero from './components/Hero';
import ProductsList from './components/ProductsList';
import Cart from './components/Cart';
import Checkout from './pages/Checkout';
import Confirmation from './pages/Confirmation';

library.add(faShoppingBag, faTimes)

class App extends Component {
constructor(props) {
super(props);

this.state = {
merchant: {},
products: [],
loading: true,
cart: {},
isCartVisible: false,
order: this.loadOrderFromLocalStorage() ?? {},
}

this.handleAddToCart = this.handleAddToCart.bind(this);
this.handleEmptyCart = this.handleEmptyCart.bind(this);
this.handleUpdateCartQty = this.handleUpdateCartQty.bind(this);
this.handleRemoveFromCart = this.handleRemoveFromCart.bind(this);
this.handleEmptyCart = this.handleEmptyCart.bind(this);
this.toggleCart = this.toggleCart.bind(this);
this.handleCaptureCheckout = this.handleEmptyCart.bind(this);
this.handleCaptureCheckout = this.handleCaptureCheckout.bind(this);
this.refreshCart = this.refreshCart.bind(this);
}

componentDidMount() {
this.fetchMerchantDetails();
this.fetchProducts();
this.fetchCart();
this.fetchCart();
this.loadOrderFromLocalStorage();
};
}

/**
* Fetch a saved order receipt from local storage so we can show the confirmation page
* again between page refreshes.
*/
loadOrderFromLocalStorage() {
if(window.localStorage.getItem('order_receipt')) {
if (window.localStorage.getItem('order_receipt')) {
return JSON.parse(window.localStorage.getItem('order_receipt'));
}
}

fetchCart() {
commerce.cart.retrieve().then((cart) => {
this.setState({ cart });
}).catch((error) => {
console.error('There was an error fetching the cart', error);
});
}

/**
* Show hide cart in nav
*/
toggleCart() {
const { isCartVisible } = this.state;
this.setState({
isCartVisible: !isCartVisible,
});
};
}

/**
* Fetch merchant details
* https://commercejs.com/docs/sdk/full-sdk-reference#merchants
*/
fetchMerchantDetails() {
commerce.merchants.about().then((merchant) => {
this.setState({ merchant: merchant });
}).catch((error) => {
console.log('There was an error fetch the merchant details', error)
});
}

/*
Fetch products data from Chec and store in the products data object.
*/
/**
* Fetch products data from Chec and stores in the products data object.
* https://commercejs.com/docs/sdk/products
*/
fetchProducts() {
commerce.products.list().then((products) => {
this.setState({ products: products.data, loading: false });
this.setState({ products: products.data });
}).catch((error) => {
console.log('There was an error fetching the products', error);
});
}

/**
* Retrieve the current cart or create one if one does not exist
* https://commercejs.com/docs/sdk/cart
*/
fetchCart() {
commerce.cart.retrieve().then((cart) => {
this.setState({ cart: cart });
}).catch((error) => {
console.error('There was an error fetching the cart', error);
});
}

/**
* Adds a product to the current cart in session
* @param {string} productId
* @param {number} quantity
* https://commercejs.com/docs/sdk/cart/#add-to-cart
*
* @param {string} productId The ID of the product being added
* @param {number} quantity The quantity of the product being added
*/
handleAddToCart(productId, quantity) {
commerce.cart.add(productId, quantity).then((item) => {
this.setState({ cart: item.cart });
this.setState({ cart: item.cart })
}).catch((error) => {
console.error('There was an error adding the item to the cart', error);
});
}


/**
* Updates line_items in cart
* @param {string} lineItemId
* @param {number} quantity
* https://commercejs.com/docs/sdk/cart/#update-cart
*
* @param {string} lineItemId ID of the cart line item being updated
* @param {number} quantity New line item quantity to update
*/
handleUpdateCartQty(lineItemId, quantity) {
commerce.cart.update(lineItemId, { quantity }).then((resp) => {
this.setState({ cart: resp.cart });
this.setState({ cart: resp.cart })
}).catch((error) => {
console.log('There was an error updating the cart items', error);
});
}


/**
* Removes line item from cart
* @param {string} lineItemId
* https://commercejs.com/docs/sdk/cart/#remove-from-cart
*
* @param {string} lineItemId ID of the line item being removed
*/
handleRemoveFromCart(lineItemId) {
commerce.cart.remove(lineItemId).then((resp) => {
this.setState({
cart: resp.cart
});
})
}).catch((error) => {
console.log('There was an error removing the item from the cart', error);
console.error('There was an error removing the item from the cart', error);
});
}


/**
* Empties cart contents
* https://commercejs.com/docs/sdk/cart/#remove-from-cart
*/
handleEmptyCart() {
commerce.cart.empty().then((resp) => {
this.setState({
cart: resp.cart
});
this.setState({ cart: resp.cart })
}).catch((error) => {
console.log('There was an error emptying the cart', error);
console.error('There was an error emptying the cart', error);
});
}

/**
* Captures the checkout
* https://commercejs.com/docs/sdk/checkout#capture-order
*
* @param {string} checkoutTokenId The ID of the checkout token
* @param {object} newOrder The new order object data
*/
handleCaptureCheckout(checkoutTokenId, newOrder) {
commerce.checkout.capture(checkoutTokenId, newOrder).then((order) => {
this.setState({
order: order,
});
//Store the order in session storage so we can show it again
// Store the order in session storage so we can show it again
// if the user refreshes the page!
window.localStorage.setItem('order_receipt', JSON.stringify(order));
// Clears the cart
this.refreshCart();
// Send the user to the receipt
this.props.history.push('/confirmation');
}).catch((error) => {
console.log('There was an error confirming your order', error);
console.log('There was an error confirming your order', error);
});
}

/**
* Refreshes to a new cart
* https://commercejs.com/docs/sdk/cart#refresh-cart
*/
refreshCart() {
commerce.cart.refresh().then((newCart) => {
Expand All @@ -163,29 +201,29 @@ class App extends Component {
return (
<div className="nav">
<div className="nav__cart" onClick={this.toggleCart}>
{!isCartVisible} ? (
<button className="nav__cart">
{!isCartVisible ? (
<button className="nav__cart-open">
<FontAwesomeIcon size="2x" icon="shopping-bag" color="#292B83"/>
{cart !== null ? <span>{cart.total_items}</span> : ''}
</button>
) : (
<button className="nav__cart-close">
<FontAwesomeIcon size="1x" icon="times" color="white"/>
</button>
)
) : (
<button className="nav__cart-close">
<FontAwesomeIcon size="1x" icon="times" color="white"/>
</button>
)}
</div>
</div>
)
}

render() {
const { products, loading, cart, isCartVisible, order } = this.state;

if(loading) {
return <p>Loading...</p>
}

console.log(this.state.cart);
const {
products,
merchant,
cart,
isCartVisible,
order
} = this.state;

return (
<div className="app">
Expand All @@ -196,18 +234,21 @@ class App extends Component {
render={(props) => {
return (
<>
<Hero
merchant={merchant}
/>
{ this.renderCartNav() }
{isCartVisible &&
{isCartVisible &&
<Cart
{...this.props}
{...props}
cart={cart}
onUpdateCartQty={this.handleUpdateCartQty}
onRemoveFromCart={this.handleRemoveFromCart}
onEmptyCart={this.handleEmptyCart}
/>
}
<ProductsList
{...this.props}
{...props}
products={products}
onAddToCart={this.handleAddToCart}
/>
Expand All @@ -221,11 +262,27 @@ class App extends Component {
render={(props) => {
return (
<Checkout
{...this.props}
{...props}
cart={cart}
onCaptureCheckout={this.handleCaptureCheckout}
/>
);
)
}}
/>
<Route
path="/confirmation"
exact
render={(props) => {
if (!order) {
return props.history.push('/');
}
return (
<Confirmation
{...props}
order={order}
onBackToHome={() => window.localStorage.removeItem('order_receipt')}
/>
)
}}
/>
</Switch>
Expand All @@ -235,3 +292,7 @@ class App extends Component {
};

export default App;

App.propTypes = {
history: PropTypes.object,
};
17 changes: 17 additions & 0 deletions src/components/Hero.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';
import PropTypes from 'prop-types';

const Hero = ({ merchant }) => {
return (
<div className="hero">
<div className="hero__text">
<h1>
{merchant.business_name}
</h1>
<a href="#products" className="btn">Shop</a>
</div>
</div>
)
}

export default Hero;
15 changes: 7 additions & 8 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,18 @@ import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import { BrowserRouter as Router } from 'react-router-dom';


ReactDOM.render(
<React.StrictMode>
<Router>
<App />
</Router>
</React.StrictMode>,
document.getElementById('root')
);
<Router>
<App/>
</Router>

, document.getElementById('root'));

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals

serviceWorker.unregister();
Loading

0 comments on commit 29ddd25

Please sign in to comment.