Skip to content

Commit 9cdcf06

Browse files
yasiloghmaniyasiloghmani
andauthored
Multi-Cart improvement (#104)
* Add pagination to multicart list + create service method to get the list + Add the method to app state * Update SDK version * Add multi cart list to Update cart and create cart + add pagination to cart modal + cart pagination * Add merge cart fetching all carts * Update cart pagination after update or edit cart and create cart * Add merge carts style * Add merge cart : Anon cart can merge to users carts * Add merge cart message + fix checkbox check issue * Fix x-scroll issue * Scroll up in modal box to top when change components * default cart name * Update SDK version , update Locals * Update en.json * Update fr.json Co-authored-by: yasiloghmani <yasaman.loghmani@EP-ML-10062.local>
1 parent d4de3d1 commit 9cdcf06

15 files changed

+409
-112
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"version": "3.0.0",
44
"private": true,
55
"dependencies": {
6-
"@moltin/sdk": "^5.5.0",
6+
"@moltin/sdk": "6.1.2",
77
"@types/node": "^12.0.0",
88
"@types/react": "^16.9.0",
99
"@types/react-dom": "^16.9.0",

src/CartItemList.tsx

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export const CartItemList: React.FC<CartItemListParams> = (props) => {
2929
const { t } = useTranslation();
3030
const { isLoggedIn } = useCustomerData();
3131
const { count, totalPrice, updateCartItems, partialAddMessage, setPartialAddMessage, addedtItem, setAddedItem} = useCartData();
32-
const { selectedCart, updateCartData } = useMultiCartData();
32+
const { selectedCart, updateCartData, setMergedMessaged, mergedMessage } = useMultiCartData();
3333
const { addError } = useContext(APIErrorContext);
3434
const quantityItems = count.toString();
3535

@@ -112,6 +112,21 @@ export const CartItemList: React.FC<CartItemListParams> = (props) => {
112112
setShowUpdateCartAlert(false);
113113
}, 4000);
114114
}, [showUpdateCartAlert])
115+
116+
useEffect(() => {
117+
window.scrollTo(0,0);
118+
})
119+
120+
useEffect(() => {
121+
const el = document.querySelector('.cartmodal__content');
122+
if(el && !newCart)
123+
{
124+
el.scrollTo({
125+
top: 0,
126+
left: 0,
127+
});
128+
}
129+
})
115130

116131
return (
117132
<div className={`cartitemlist ${isLoading ? '--loading' : ''}`}>
@@ -120,29 +135,35 @@ export const CartItemList: React.FC<CartItemListParams> = (props) => {
120135
{t('my-carts')}
121136
</button>
122137
)}
138+
123139
{showUpdateCartAlert && (
124140
<div className="cartslist__alertMessage">
125141
<p>{t('update-cart-message')}</p>
126142
<CloseIcon onClick={() => setShowUpdateCartAlert(false)}/>
127143
</div>
128144
)}
145+
146+
{mergedMessage && (
147+
<div className="cartslist__alertMessage">
148+
<p>{mergedMessage}</p>
149+
<CloseIcon onClick={() => setMergedMessaged("")}/>
150+
</div>
151+
)}
129152

130-
<div className="partialadd">
131-
{addedtItem && ( <div className="partialadd__confirmationmessage">
132-
<p>{addedtItem} items have been added to the cart</p>
133-
<CloseIcon onClick={() => setAddedItem("")}/>
134-
</div>
135-
)}
136-
{partialAddMessage && (
137-
<div className="partialadd__alertMessage">
138-
<p>{partialAddMessage}</p>
139-
<CloseIcon onClick={() => setPartialAddMessage("")}/>
140-
</div>
141-
)}
153+
<div className="partialadd">
154+
{addedtItem && ( <div className="partialadd__confirmationmessage">
155+
<p>{addedtItem} {t("items-added-to-the-cart")}</p>
156+
<CloseIcon onClick={() => setAddedItem("")}/>
142157
</div>
158+
)}
159+
{partialAddMessage && (
160+
<div className="partialadd__alertMessage">
161+
<p>{partialAddMessage}</p>
162+
<CloseIcon onClick={() => setPartialAddMessage("")}/>
163+
</div>
164+
)}
165+
</div>
143166

144-
145-
146167
<div className="cartitemlist__header">
147168
<h2 className="cartitemlist__title">
148169
{isLoggedIn && selectedCart ? (

src/CartModal.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
bottom: 0px;
2323
right: 0px;
2424
overflow-y: scroll;
25+
overflow-x: hidden;
2526
height: 100%;
2627
min-height: 100%;
2728
width: 100%;

src/CartModal.tsx

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { CartsList } from "./CartsList";
1313
import { ReactComponent as CloseIcon } from './images/icons/ic_close.svg';
1414
import { ReactComponent as BackArrowIcon } from './images/icons/arrow_back-black-24dp.svg';
1515
import { APIErrorContext } from "./APIErrorProvider";
16+
import { CartsPagination } from './CartsPagination';
1617

1718
import './CartModal.scss';
1819
import {OrderDetailsTable} from './OrderDetailsTable';
@@ -55,7 +56,7 @@ export const CartModal: React.FC<CartModalParams> = (props) => {
5556
const { cartData, promotionItems, updateCartItems } = useCartData();
5657
const { isLoggedIn } = useCustomerData();
5758
const { updatePurchaseHistory } = useOrdersData();
58-
const { isCartSelected, isCreateNewCart, updateCartData } = useMultiCartData();
59+
const { isCartSelected, isCreateNewCart, updateCartData, total, currentPage } = useMultiCartData();
5960
const { t } = useTranslation();
6061
const { addError } = useContext(APIErrorContext);
6162

@@ -185,10 +186,15 @@ export const CartModal: React.FC<CartModalParams> = (props) => {
185186
/>
186187
)}
187188
{isLoggedIn && route === 'cartsList' && (
188-
<CartsList
189-
onHandlePage={(page: string) => handlePage(page)}
190-
handleHideBackButton={(value:boolean) => {setHideBackButton(value)}}
191-
/>
189+
<>
190+
<CartsList
191+
onHandlePage={(page: string) => handlePage(page)}
192+
handleHideBackButton={(value:boolean) => {setHideBackButton(value)}}
193+
/>
194+
<CartsPagination totalPages={total}
195+
currentPage={currentPage} />
196+
</>
197+
192198
)}
193199
{route === 'shipping' && (
194200
<div>

src/CartsList.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
.cartslist {
44
$block: &;
55
text-align: center;
6+
margin-bottom: 25px;
67

78
&__editview {
89
display: block;

src/CartsList.tsx

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { ReactComponent as ArrowRightIcon } from "./images/icons/keyboard_arrow_
88
import { ReactComponent as DeleteIcon } from "./images/icons/delete-black-24dp.svg";
99
import { ReactComponent as CloseIcon } from "./images/icons/ic_close.svg";
1010

11+
1112
import './CartsList.scss';
1213

1314
interface CartsListParams {
@@ -17,7 +18,7 @@ interface CartsListParams {
1718

1819
export const CartsList: React.FC<CartsListParams> = (props) => {
1920
const { onHandlePage } = props;
20-
const { multiCartData, updateSelectedCart, setIsCartSelected, updateCartData } = useMultiCartData();
21+
const { multiCartData, updateSelectedCart, setIsCartSelected, updateCartData, multiCartDataList } = useMultiCartData();
2122
const { updateCartItems } = useCartData();
2223
const [selectedCarts, setSelectedCarts] = useState<string[]>([]);
2324
const [deletedCartNumber , setDeletedCartNumber] = useState(Number);
@@ -39,7 +40,7 @@ export const CartsList: React.FC<CartsListParams> = (props) => {
3940
};
4041

4142
const handleSelectAll = () => {
42-
const allCarts = multiCartData.map((cart: moltin.Cart) => cart.id);
43+
const allCarts = multiCartDataList.map((cart: moltin.Cart) => cart.id);
4344
if(selectedCarts.length < allCarts.length) {
4445
setSelectedCarts(allCarts);
4546
} else {
@@ -93,6 +94,18 @@ export const CartsList: React.FC<CartsListParams> = (props) => {
9394
setShowCreateCartAlert(false)
9495
}, 4000);
9596
}, [showCreateCartAlert]);
97+
98+
99+
useEffect(() => {
100+
const el = document.querySelector('.cartmodal__content');
101+
if(el && showSettings)
102+
{
103+
el.scrollTo({
104+
top: 0,
105+
left: 0,
106+
});
107+
}
108+
})
96109

97110
return (
98111
<div className="cartslist">
@@ -109,34 +122,34 @@ export const CartsList: React.FC<CartsListParams> = (props) => {
109122
</div>
110123
)}
111124
<div className="cartslist__content">
112-
{multiCartData.length && (
125+
{multiCartDataList.length && (
113126
<button className="cartslist__editbutton" onClick={handleCartEdit}>
114127
{t(isEdit ? 'done' : 'edit')}
115128
</button>
116129
)}
117130
<h2 className="cartslist__title">
118131
{t('my-carts')}
119132
</h2>
120-
{multiCartData && multiCartData.length ? (
133+
{multiCartDataList && multiCartDataList.length ? (
121134
<div>
122135
<div className="cartslist__editview">
123136
<div className="cartslist__selectedtitle">
124137
<div className={`${isEdit ? 'isshow' : ''}`}>
125138
<span>
126-
<input type="checkbox" name="cartCheck" id="select-all" className="cartslist__checkall epcheckbox" checked={selectedCarts.length === multiCartData.length} onChange={() => {handleSelectAll()}} />
139+
<input type="checkbox" name="cartCheck" id="select-all" className="cartslist__checkall epcheckbox" checked={selectedCarts.length === multiCartDataList.length} onChange={() => {handleSelectAll()}} />
127140
<label htmlFor="select-all" className="">
128141
{selectedCarts.length === 1 ? `${selectedCarts.length} ${t('cart')}
129142
${t('selected')}` : `${selectedCarts.length} ${t('carts')}
130143
${t('selected')}` }
131144
</label>
132145
</span>
133-
<button className="cartslist__deletebutton" disabled={selectedCarts.length === 0 || multiCartData.length === 1} onClick={() => setIsShowModal(true)}>
146+
<button className="cartslist__deletebutton" disabled={selectedCarts.length === 0 || multiCartDataList.length === 1} onClick={() => setIsShowModal(true)}>
134147
{!isShowModal ? <DeleteIcon /> : <span className="circularLoader" aria-label={t('loading')} />}
135148
</button>
136149
</div>
137150
</div>
138151
<div className={`cartslist__cartlist${isEdit ? ' --editmode' : ''}`}>
139-
{multiCartData.map((cart: any) => (
152+
{multiCartDataList.map((cart: any) => (
140153
<div role="presentation" className='cartslist__cartelement' key={cart.id} onClick={() => handleCart(cart)} tabIndex={-1}>
141154
{isEdit && (
142155
<input type="checkbox" name="cartCheck" id={`cart_${cart.id}`} className="cartslist__check epcheckbox" checked={selectedCarts.includes(cart.id)} onChange={() => {handleSelectCart(cart.id)}} />
@@ -187,8 +200,8 @@ export const CartsList: React.FC<CartsListParams> = (props) => {
187200
</div>
188201
</div>
189202
<div className={`cartslist__cartlist${isEdit ? ' --editmode' : ''}`}>
190-
{multiCartData.map((cart: any) => (
191-
<div className='cartslist__cartelement'>
203+
{multiCartDataList.map((cart: any) => (
204+
<div className='cartslist__cartelement' key={cart.id}>
192205
<input type="checkbox" name="cartCheck" id={`cart_${cart.id}`} className="cartslist__check epcheckbox" checked={selectedCarts.includes(cart.id)} onChange={() => {handleSelectCart(cart.id)}} />
193206
<label htmlFor={`cart_${cart.id}`} className="cartslist__description">
194207
<div role="presentation" key={cart.id} onClick={() => handleCart(cart)} tabIndex={-1}>
@@ -248,6 +261,7 @@ export const CartsList: React.FC<CartsListParams> = (props) => {
248261
<div className="cartslist__confirmationoverlay" />
249262
</React.Fragment>
250263
)}
264+
251265
<SettingsCart showSettings={showSettings} handleHideSettings={() => setShowSettings(false)} setShowCartAlert={() => setShowCreateCartAlert(true)}/>
252266
</div>
253267
)

src/CartsPagination.scss

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,40 @@
11
@import './theme/common.scss';
22

33
.CartsPagination {
4-
position: relative;
5-
bottom: 0;
4+
position: absolute;
5+
bottom: 25px;
66
font-style: normal;
77
font-weight: normal;
88
font-size: 13px;
99
line-height: 15px;
1010
text-align: center;
11+
left: 50%;
12+
transform: translate(-50%, 0);
1113

1214
&__pagenumber {
1315
font-style: normal;
1416
font-weight: normal;
1517
font-size: 13px;
1618
line-height: 15px;
1719
text-align: center;
20+
padding: 0 10px;
1821
}
1922

2023
&__prevpageicon {
2124
transform: rotate(90deg);
25+
2226
}
2327

2428
&__nextpageicon {
2529
transform: rotate(-90deg);
30+
2631
}
2732

2833
svg {
29-
fill: #3C4858;
34+
path{
35+
fill: #3C4858;
36+
}
37+
3038
cursor: pointer;
3139

3240
&:hover{

src/CartsPagination.tsx

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,33 @@
11
import React from 'react';
2+
import { useMultiCartData } from './app-state';
23
import { ReactComponent as PaginationIcon } from "./images/icons/ic_caret.svg";
34

45
import './CartsPagination.scss';
56

67
export interface Props {
7-
page: number;
8+
currentPage: number;
89
totalPages: number;
9-
// handlePagination: (page: number) => void;
1010
}
1111
export const CartsPagination: React.FC<Props> = ({
12-
page,
12+
currentPage,
1313
totalPages,
14-
// handlePagination,
1514
}) => {
15+
16+
const { setPageNum} = useMultiCartData();
1617
return (
1718
<div className="CartsPagination">
18-
{page !== 1 && (
19-
<PaginationIcon className="CartsPagination__prevpageicon" />
19+
{currentPage !== 1 && (
20+
<button onClick={() => setPageNum(currentPage-1)}> <PaginationIcon className="CartsPagination__prevpageicon"/></button>
2021
)}
22+
2123
<span className="CartsPagination__pagenumber">
22-
Page {page} of {totalPages}
24+
Page {currentPage} of {totalPages}
2325
</span>
24-
{page !== totalPages && (
25-
<PaginationIcon className="CartsPagination__nextpageicon" />
26+
27+
{currentPage !== totalPages && (
28+
<button onClick={() => setPageNum(currentPage+1)}> <PaginationIcon className="CartsPagination__nextpageicon" /></button>
2629
)}
30+
2731
</div>
2832
);
2933
};

0 commit comments

Comments
 (0)