1
0
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:
Du Peng 2022-09-08 16:27:34 +02:00
parent 8d414a3172
commit aeae5f7aa0
6 changed files with 37 additions and 22 deletions

View File

@ -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>
);

View File

@ -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);
};
/**

View File

@ -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']));

View File

@ -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>

View File

@ -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 };
}

View File

@ -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>