mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2024-12-01 12:24:28 +01:00
(feat) add product to cart in product page
This commit is contained in:
parent
8d414a3172
commit
aeae5f7aa0
@ -28,7 +28,9 @@ const CartButton: React.FC = () => {
|
||||
return (
|
||||
<div className="cart-button" onClick={showCart}>
|
||||
<i className="fas fa-cart-arrow-down" />
|
||||
<span>{cart?.order_items_attributes?.length}</span>
|
||||
{cart && cart.order_items_attributes.length > 0 &&
|
||||
<span>{cart.order_items_attributes.length}</span>
|
||||
}
|
||||
<p>{t('app.public.cart_button.my_cart')}</p>
|
||||
</div>
|
||||
);
|
||||
|
@ -11,13 +11,14 @@ import noImage from '../../../../images/no_image.png';
|
||||
interface StoreProductItemProps {
|
||||
product: Product,
|
||||
cart: Order,
|
||||
onSuccessAddProductToCart: (cart: Order) => void
|
||||
onSuccessAddProductToCart: (cart: Order) => void,
|
||||
onError: (message: string) => void
|
||||
}
|
||||
|
||||
/**
|
||||
* This component shows a product item in store
|
||||
*/
|
||||
export const StoreProductItem: React.FC<StoreProductItemProps> = ({ product, cart, onSuccessAddProductToCart }) => {
|
||||
export const StoreProductItem: React.FC<StoreProductItemProps> = ({ product, cart, onSuccessAddProductToCart, onError }) => {
|
||||
const { t } = useTranslation('public');
|
||||
|
||||
/**
|
||||
@ -37,7 +38,7 @@ export const StoreProductItem: React.FC<StoreProductItemProps> = ({ product, car
|
||||
const addProductToCart = (e: React.BaseSyntheticEvent) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
CartAPI.addItem(cart, product.id, 1).then(onSuccessAddProductToCart);
|
||||
CartAPI.addItem(cart, product.id, 1).then(onSuccessAddProductToCart).catch(onError);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -7,24 +7,30 @@ import { Loader } from '../base/loader';
|
||||
import { IApplication } from '../../models/application';
|
||||
import _ from 'lodash';
|
||||
import { Product } from '../../models/product';
|
||||
import { User } from '../../models/user';
|
||||
import ProductAPI from '../../api/product';
|
||||
import CartAPI from '../../api/cart';
|
||||
import noImage from '../../../../images/no_image.png';
|
||||
import { FabButton } from '../base/fab-button';
|
||||
import useCart from '../../hooks/use-cart';
|
||||
import { FilePdf, Minus, Plus } from 'phosphor-react';
|
||||
|
||||
declare const Application: IApplication;
|
||||
|
||||
interface StoreProductProps {
|
||||
productSlug: string,
|
||||
onSuccess: (message: string) => void,
|
||||
onError: (message: string) => void,
|
||||
currentUser?: User
|
||||
}
|
||||
|
||||
/**
|
||||
* This component shows a product
|
||||
*/
|
||||
export const StoreProduct: React.FC<StoreProductProps> = ({ productSlug, onError }) => {
|
||||
export const StoreProduct: React.FC<StoreProductProps> = ({ productSlug, currentUser, onSuccess, onError }) => {
|
||||
const { t } = useTranslation('public');
|
||||
|
||||
const { cart, setCart } = useCart(currentUser);
|
||||
const [product, setProduct] = useState<Product>();
|
||||
const [showImage, setShowImage] = useState<number>(null);
|
||||
const [toCartCount, setToCartCount] = useState<number>(0);
|
||||
@ -36,11 +42,13 @@ export const StoreProduct: React.FC<StoreProductProps> = ({ productSlug, onError
|
||||
ProductAPI.get(productSlug).then(data => {
|
||||
setProduct(data);
|
||||
const productImage = _.find(data.product_images_attributes, { is_main: true });
|
||||
setShowImage(productImage.id);
|
||||
if (productImage) {
|
||||
setShowImage(productImage.id);
|
||||
}
|
||||
setToCartCount(data.quantity_min ? data.quantity_min : 1);
|
||||
setDisplayToggle(descContainer.current.offsetHeight < descContainer.current.scrollHeight);
|
||||
}).catch(() => {
|
||||
onError(t('app.public.store_product.unexpected_error_occurred'));
|
||||
}).catch((e) => {
|
||||
onError(t('app.public.store_product.unexpected_error_occurred') + e);
|
||||
});
|
||||
}, []);
|
||||
|
||||
@ -107,7 +115,10 @@ export const StoreProduct: React.FC<StoreProductProps> = ({ productSlug, onError
|
||||
* Add product to cart
|
||||
*/
|
||||
const addToCart = () => {
|
||||
console.log('Add', toCartCount, 'to cart');
|
||||
CartAPI.addItem(cart, product.id, toCartCount).then(data => {
|
||||
setCart(data);
|
||||
onSuccess(t('app.public.store.add_to_cart_success'));
|
||||
}).catch(onError);
|
||||
};
|
||||
|
||||
if (product) {
|
||||
@ -187,12 +198,12 @@ export const StoreProduct: React.FC<StoreProductProps> = ({ productSlug, onError
|
||||
return null;
|
||||
};
|
||||
|
||||
const StoreProductWrapper: React.FC<StoreProductProps> = ({ productSlug, onError }) => {
|
||||
const StoreProductWrapper: React.FC<StoreProductProps> = (props) => {
|
||||
return (
|
||||
<Loader>
|
||||
<StoreProduct productSlug={productSlug} onError={onError} />
|
||||
<StoreProduct {...props} />
|
||||
</Loader>
|
||||
);
|
||||
};
|
||||
|
||||
Application.Components.component('storeProduct', react2angular(StoreProductWrapper, ['productSlug', 'onError']));
|
||||
Application.Components.component('storeProduct', react2angular(StoreProductWrapper, ['productSlug', 'currentUser', 'onSuccess', 'onError']));
|
||||
|
@ -11,7 +11,6 @@ import ProductCategoryAPI from '../../api/product-category';
|
||||
import MachineAPI from '../../api/machine';
|
||||
import { StoreProductItem } from './store-product-item';
|
||||
import useCart from '../../hooks/use-cart';
|
||||
import { emitCustomEvent } from 'react-custom-events';
|
||||
import { User } from '../../models/user';
|
||||
import { Order } from '../../models/order';
|
||||
import { AccordionItem } from './accordion-item';
|
||||
@ -67,10 +66,6 @@ const Store: React.FC<StoreProps> = ({ onError, onSuccess, currentUser }) => {
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
emitCustomEvent('CartUpdate', cart);
|
||||
}, [cart]);
|
||||
|
||||
/**
|
||||
* Create categories tree (parent/children)
|
||||
*/
|
||||
@ -234,7 +229,7 @@ const Store: React.FC<StoreProps> = ({ onError, onSuccess, currentUser }) => {
|
||||
/>
|
||||
<div className="products-grid">
|
||||
{products.map((product) => (
|
||||
<StoreProductItem key={product.id} product={product} cart={cart} onSuccessAddProductToCart={addToCart} />
|
||||
<StoreProductItem key={product.id} product={product} cart={cart} onSuccessAddProductToCart={addToCart} onError={onError} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { emitCustomEvent } from 'react-custom-events';
|
||||
import { Order } from '../models/order';
|
||||
import CartAPI from '../api/cart';
|
||||
import { getCartToken, setCartToken } from '../lib/cart-token';
|
||||
@ -13,7 +14,7 @@ export default function useCart (user?: User) {
|
||||
async function createCart () {
|
||||
const currentCartToken = getCartToken();
|
||||
const data = await CartAPI.create(currentCartToken);
|
||||
setCart(data);
|
||||
_setCart(data);
|
||||
setLoading(false);
|
||||
setCartToken(data.token);
|
||||
}
|
||||
@ -30,7 +31,7 @@ export default function useCart (user?: User) {
|
||||
setLoading(true);
|
||||
const currentCartToken = getCartToken();
|
||||
const data = await CartAPI.create(currentCartToken);
|
||||
setCart(data);
|
||||
_setCart(data);
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
@ -40,5 +41,10 @@ export default function useCart (user?: User) {
|
||||
}
|
||||
}, [user]);
|
||||
|
||||
return { loading, cart, error, setCart, reloadCart };
|
||||
const _setCart = (data: Order) => {
|
||||
setCart(data);
|
||||
emitCustomEvent('CartUpdate', data);
|
||||
};
|
||||
|
||||
return { loading, cart, error, setCart: _setCart, reloadCart };
|
||||
}
|
||||
|
@ -13,5 +13,5 @@
|
||||
</div>
|
||||
|
||||
<section class="m-lg">
|
||||
<store-product product-slug="productSlug" on-error="onError" on-success="onSuccess" />
|
||||
<store-product product-slug="productSlug" current-user="currentUser" on-error="onError" on-success="onSuccess" />
|
||||
</section>
|
||||
|
Loading…
Reference in New Issue
Block a user