CartPage.jsx 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import Breadcrumb from "../components/Breadcrumbs";
  2. import {connect} from "react-redux";
  3. import {actionCardChange, actionCardClear, actionCardRemove} from "../reducers/CartReducer";
  4. import {ActionFullOrder, ActionOrder} from "../actions/ActionOrder";
  5. import {Box, Button, Container, Divider, Grid, Typography, useMediaQuery} from "@mui/material";
  6. import {ItemHeaderLine, LinkProductItem, RemoveFromList, TableLine} from "../components/TableLine";
  7. import {NotFoundBlock} from "../components/NotFoundBlock";
  8. import imgUrl from "../img/not-found/3.png";
  9. import AddShoppingCartIcon from "@mui/icons-material/AddShoppingCart";
  10. import {SetCount} from "../components/SetCount";
  11. import {useEffect, useState} from "react";
  12. const CartGoodLine = ({item, onCartRemove, onCardChange}) => {
  13. let [count, setCount] = useState(item?.count)
  14. useEffect(() => {
  15. onCardChange(item?.good, count)
  16. }, [count])
  17. return(
  18. <Grid container alignItems='center' marginBottom='20px'>
  19. <Grid item xs={6}>
  20. <LinkProductItem item={[item?.good?._id, item?.good?.name, item?.good?.images]} children={<Typography>${item?.good?.price}</Typography>}/>
  21. </Grid>
  22. <Grid item xs={3} display='flex' justifyContent="center">
  23. <SetCount height={40} width={40} defaultValue={item?.count} onCount={value => setCount(value)}/>
  24. </Grid>
  25. <Grid item xs={2}>
  26. <ItemHeaderLine align={'center'} text={(`$${parseFloat(item?.good?.price * count).toFixed(2)}`) || 'NaN'}/>
  27. </Grid>
  28. <Grid item xs={1}>
  29. <RemoveFromList good={item?.good} onRemove={onCartRemove}/>
  30. </Grid>
  31. </Grid>
  32. )
  33. }
  34. const TotalPriceLine = ({title, subtitle, sizeSubtitle='body2'}) => {
  35. return (
  36. <Grid container display='flex' flexDirection='row' justifyContent='space-between' alignItems='center' padding='20px'>
  37. <Grid item xs={6}>
  38. <Typography
  39. variant='body2'
  40. color='#616161'
  41. textAlign='left'
  42. >
  43. {title}
  44. </Typography>
  45. </Grid>
  46. <Grid item xs={6}>
  47. <Typography
  48. variant={sizeSubtitle}
  49. color='#000'
  50. textAlign='right'
  51. >
  52. {subtitle}
  53. </Typography>
  54. </Grid>
  55. </Grid>
  56. )
  57. }
  58. const CartPage = ({cart, onCardChange, onCartClear, onCartRemove, onOrderUpsert}) => {
  59. const matches = useMediaQuery('(max-width:768px)')
  60. let rows = []
  61. for (const key of Object.values(cart)) {
  62. rows.push(key)
  63. }
  64. return (
  65. <>
  66. <Breadcrumb links={['cart']}/>
  67. {Object.values(cart).length > 0 ?
  68. <main style={{backgroundColor: "#f3f3f3", padding: matches ? "20px 0" : "50px 0", minHeight:'300px'}}>
  69. <Container maxWidth="lg">
  70. <Grid container justifyContent='space-between'>
  71. <Grid item xs={8.5}>
  72. <TableLine columnName={['PRODUCT', 'QUANTITY', 'REMOVE', 'SUBTOTAL']} customSizeCol={[6, 3, 2, 1]}/>
  73. <Divider sx={{marginBottom: '20px'}}/>
  74. {rows.map(item => <CartGoodLine item={item} onCartRemove={onCartRemove} onCardChange={onCardChange}/>)}
  75. <Divider/>
  76. </Grid>
  77. <Grid item xs={3} sx={{backgroundColor: '#fff'}} height='100%' paddingBottom='20px'>
  78. <Typography
  79. padding='20px'
  80. variant='h4'
  81. fontFamily='sarif'
  82. letterSpacing='2px'
  83. textAlign='center'
  84. >
  85. TOTAL
  86. </Typography>
  87. <Divider/>
  88. <TotalPriceLine title={`${rows.length || 1} goods for the amount`} subtitle={`$${rows.reduce((a, i) => a + (i.good.price * i.count), 0)}`}/>
  89. <TotalPriceLine title={'Cost of delivery'} subtitle={'according to the carrier\'s tariffs'}/>
  90. <Divider/>
  91. <TotalPriceLine title={'To pay'} subtitle={`$${rows.reduce((a, i) => a + (i.good.price * i.count), 0)}`} sizeSubtitle={'h6'}/>
  92. <Divider sx={{marginBottom: '20px'}}/>
  93. <Box display='flex' justifyContent='center' flexDirection='column' alignItems='center'>
  94. <Button sx={{borderRadius: '0', width:'80%', padding: '10px 20px', marginBottom: '20px'}}
  95. color='success'
  96. variant="outlined"
  97. onClick={() => onOrderUpsert(cart)}
  98. >
  99. confirm the order
  100. </Button>
  101. <Button sx={{borderRadius: '0', width:'80%', padding: '10px 20px'}}
  102. color='warning'
  103. variant="outlined"
  104. onClick={() => onCartClear()}
  105. >
  106. cart clear
  107. </Button>
  108. </Box>
  109. </Grid>
  110. </Grid>
  111. </Container>
  112. </main>:
  113. <NotFoundBlock img={imgUrl} headerText={'YOUR CART IS CURRENTLY EMPTY'} text={<Box display='flex' alignItems='center'><Typography component='span'>Click the</Typography><AddShoppingCartIcon sx={{margin: '0 10px'}}/><Typography component='span'>icons to add products</Typography></Box>}/>
  114. }
  115. </>
  116. )
  117. }
  118. const CCartPage = connect(state=>({cart: state.cart}), {onCardChange: actionCardChange, onCartClear: actionCardClear, onCartRemove: actionCardRemove, onOrderUpsert: ActionFullOrder})(CartPage)
  119. export default CCartPage