Skip to content

Commit 57d5e72

Browse files
committed
feat: complete mobile design of BuyBox
1 parent 3f4ef90 commit 57d5e72

File tree

4 files changed

+145
-80
lines changed

4 files changed

+145
-80
lines changed

src/app/[locale]/(main)/(container)/layout.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
import {
2+
MOBILE_BUY_BOX_HEIGHT,
3+
MOBILE_FOOTER_HEIGHT,
4+
} from '@/config/responsive';
15
import { Container } from '@mui/material';
26
import { FC, ReactNode } from 'react';
37

@@ -9,7 +13,11 @@ const Layout: FC<Layout> = async ({ children }) => {
913
return (
1014
<Container
1115
maxWidth="xl"
12-
sx={{ mt: 3, pb: { xs: '56px', md: 0 }, minHeight: '70vh' }}
16+
sx={{
17+
mt: 3,
18+
pb: { xs: `${MOBILE_FOOTER_HEIGHT + MOBILE_BUY_BOX_HEIGHT}px`, md: 0 },
19+
minHeight: '70vh',
20+
}}
1321
>
1422
{children}
1523
</Container>

src/app/[locale]/(main)/(container)/products/[...params]/components/BuyBox.tsx

Lines changed: 92 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import DiscountPercentage from '../../../../../../../components/common/DiscountP
3535
import OldPrice from '../../../../../../../components/common/OldPrice';
3636
import PriceLabel from '../../../../../../../components/common/PriceLabel';
3737
import AddToCartDialog from './AddToCartDialog';
38+
import MobileBuyBox from './MobileBuyBox';
3839

3940
const listItems = [
4041
{
@@ -117,6 +118,89 @@ const BuyBox: FC<BuyBoxProps> = ({ product }) => {
117118
(variant === null && product?.discountPercentage) ||
118119
(variant !== null && variant?.discountPercentage);
119120

121+
const priceSection = (
122+
<Box
123+
sx={{
124+
display: 'flex',
125+
flexDirection: 'column',
126+
alignItems: 'end',
127+
gap: 1,
128+
}}
129+
>
130+
<Box
131+
sx={{
132+
display: 'flex',
133+
gap: 0.5,
134+
}}
135+
>
136+
{!!discountPercentage && (
137+
<>
138+
<OldPrice
139+
value={variant ? variant?.regularPrice : product.regularPrice}
140+
TypographyProps={{
141+
variant: 'body1',
142+
}}
143+
/>
144+
145+
<DiscountPercentage
146+
value={
147+
variant
148+
? variant.discountPercentage
149+
: product.discountPercentage
150+
}
151+
/>
152+
</>
153+
)}
154+
</Box>
155+
<PriceLabel
156+
TypographyProps={{
157+
variant: 'h6',
158+
fontWeight: 600,
159+
}}
160+
value={variant ? variant.price : product.price}
161+
/>
162+
</Box>
163+
);
164+
165+
const controllerSection = (
166+
<Box>
167+
{/* TODO: Handle out of stock state */}
168+
{!itemInCart && (
169+
<ButtonWithLoading
170+
isLoading={addOrUpdateCartItemLoading}
171+
fullWidth
172+
variant="contained"
173+
color="primary"
174+
size="large"
175+
onClick={handleClickOnAdd}
176+
sx={{ minHeight: height }}
177+
>
178+
{t('buttons.addToCart')}
179+
</ButtonWithLoading>
180+
)}
181+
182+
{itemInCart && (
183+
<>
184+
<Box height={height}>
185+
<CartItemController item={itemInCart} />
186+
</Box>
187+
<Collapse appear in={true}>
188+
<Stack direction="row" justifyContent="center" spacing={1}>
189+
<Typography variant="body2">
190+
{t('pages.product.buyBox.inYourCart')}
191+
</Typography>
192+
<Link href="/cart">
193+
<Typography color="primary" variant="body2">
194+
{t('pages.product.buyBox.viewCart')}
195+
</Typography>
196+
</Link>
197+
</Stack>
198+
</Collapse>
199+
</>
200+
)}
201+
</Box>
202+
);
203+
120204
return (
121205
<>
122206
<AddToCartDialog
@@ -174,86 +258,15 @@ const BuyBox: FC<BuyBoxProps> = ({ product }) => {
174258
})}
175259
</List>
176260

177-
<Box
178-
sx={{
179-
display: 'flex',
180-
flexDirection: 'column',
181-
alignItems: 'end',
182-
gap: 1,
183-
}}
184-
>
185-
<Box
186-
sx={{
187-
display: 'flex',
188-
gap: 0.5,
189-
}}
190-
>
191-
{!!discountPercentage && (
192-
<>
193-
<OldPrice
194-
value={
195-
variant ? variant?.regularPrice : product.regularPrice
196-
}
197-
TypographyProps={{
198-
variant: 'body1',
199-
}}
200-
/>
261+
{isMobile && (
262+
<MobileBuyBox>
263+
<Box width="55%">{controllerSection}</Box>
264+
{priceSection}
265+
</MobileBuyBox>
266+
)}
201267

202-
<DiscountPercentage
203-
value={
204-
variant
205-
? variant.discountPercentage
206-
: product.discountPercentage
207-
}
208-
/>
209-
</>
210-
)}
211-
</Box>
212-
<PriceLabel
213-
TypographyProps={{
214-
variant: 'h6',
215-
fontWeight: 600,
216-
}}
217-
value={variant ? variant.price : product.price}
218-
/>
219-
</Box>
220-
221-
<Box>
222-
{/* TODO: Handle out of stock state */}
223-
{!itemInCart && (
224-
<ButtonWithLoading
225-
isLoading={addOrUpdateCartItemLoading}
226-
fullWidth
227-
variant="contained"
228-
color="primary"
229-
size="large"
230-
onClick={handleClickOnAdd}
231-
sx={{ minHeight: height }}
232-
>
233-
{t('buttons.addToCart')}
234-
</ButtonWithLoading>
235-
)}
236-
237-
{itemInCart && (
238-
<>
239-
<Box height={height}>
240-
<CartItemController item={itemInCart} />
241-
</Box>
242-
<Collapse appear in={true}>
243-
<Stack direction="row" justifyContent="center" spacing={1}>
244-
<Typography variant="body2">
245-
{t('pages.product.buyBox.inYourCart')}
246-
</Typography>
247-
<Link href="/cart">
248-
<Typography color="primary" variant="body2">
249-
{t('pages.product.buyBox.viewCart')}
250-
</Typography>
251-
</Link>
252-
</Stack>
253-
</Collapse>
254-
</>
255-
)}
256-
</Box>
268+
{!isMobile && priceSection}
269+
{!isMobile && controllerSection}
257270
</Box>
258271
)}
259272
</>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import {
2+
MOBILE_BUY_BOX_HEIGHT,
3+
MOBILE_FOOTER_HEIGHT,
4+
} from '@/config/responsive';
5+
import { Stack } from '@mui/material';
6+
import { FC, PropsWithChildren } from 'react';
7+
8+
export interface MobileBuyBoxProps {}
9+
const MobileBuyBox: FC<PropsWithChildren<MobileBuyBoxProps>> = ({
10+
children,
11+
}) => {
12+
return (
13+
<Stack
14+
sx={{
15+
position: 'fixed',
16+
bottom: MOBILE_FOOTER_HEIGHT,
17+
left: 0,
18+
right: 0,
19+
height: MOBILE_BUY_BOX_HEIGHT,
20+
backgroundColor: (theme) => theme.palette.background.default,
21+
boxShadow: (theme) => theme.shadows[2],
22+
px: 3,
23+
}}
24+
spacing={1}
25+
alignItems="center"
26+
justifyContent="center"
27+
>
28+
<Stack
29+
direction="row"
30+
spacing={1}
31+
width="100%"
32+
justifyContent="space-between"
33+
alignItems="center"
34+
height="100%"
35+
>
36+
{children}
37+
</Stack>
38+
</Stack>
39+
);
40+
};
41+
42+
export default MobileBuyBox;

src/config/responsive.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export const MOBILE_FOOTER_HEIGHT = 56;
2+
export const MOBILE_BUY_BOX_HEIGHT = MOBILE_FOOTER_HEIGHT * 1.8;

0 commit comments

Comments
 (0)